From 41bf0e0ab7d6affb3415abd8cecd2011831f50d1 Mon Sep 17 00:00:00 2001 From: Gary Gan Date: Thu, 12 Jun 2025 14:52:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E6=B7=BB=E6=B5=8B=E8=AF=95=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 7 ++- semantic/rule.py | 108 +++++++++----------------------------------- syntax/rule.py | 6 +-- test.c | 18 -------- test1.c => test1.hy | 35 +++++++------- test2.c | 14 ------ test2.hy | 16 +++++++ test3.c | 21 --------- test3.hy | 22 +++++++++ test4.c | 19 -------- test4.hy | 20 ++++++++ test5.c | 29 ------------ test5.hy | 20 ++++++++ test6.c | 13 ------ test8.c => test6.hy | 38 ++++++++-------- test7.c | 19 -------- test9.c => test7.hy | 0 17 files changed, 145 insertions(+), 260 deletions(-) delete mode 100644 test.c rename test1.c => test1.hy (58%) delete mode 100644 test2.c create mode 100644 test2.hy delete mode 100644 test3.c create mode 100644 test3.hy delete mode 100644 test4.c create mode 100644 test4.hy delete mode 100644 test5.c create mode 100644 test5.hy delete mode 100644 test6.c rename test8.c => test6.hy (60%) delete mode 100644 test7.c rename test9.c => test7.hy (100%) diff --git a/main.py b/main.py index 79e7781..3a6fcf6 100644 --- a/main.py +++ b/main.py @@ -4,6 +4,7 @@ from lexical.lexical import Lexical from syntax.syntax import Syntax from syntax.syntax import LL1Generator +import sys # print(PredictingAnalysisTable().compile()) @@ -13,8 +14,12 @@ from syntax.syntax import LL1Generator # 新建词法分析器 lexical = Lexical() +if len(sys.argv) < 2: + print("请提供源代码文件名作为参数。") + sys.exit(1) +source_filename = sys.argv[1] # 载入源代码 -lexical.load_source(open('test9.c', encoding='utf-8', errors='ignore').read()) +lexical.load_source(open(source_filename, encoding='utf-8', errors='ignore').read()) # 执行词法分析 lexical_success = lexical.execute() # 打印结果 diff --git a/semantic/rule.py b/semantic/rule.py index 3614459..e973f99 100644 --- a/semantic/rule.py +++ b/semantic/rule.py @@ -4,91 +4,6 @@ from semantic.code import get_temp_block_name, get_temp_var_name -""" -添加语义规则的文法 -0. program{code} ->{.init} define-list -1. define-list{code} -> define define-list - {code} | empty -2. define{code} -> type ID define-type{type id} -3. define-type{code .enter} ->{.judge} var-define-follow{type id} - {code} |{.judge} fun-define-follow{type fun} -4. var-define-follow{type} -> ; - {type length} | [ NUM ] ; -5. type ->{type} int - |{type} void -6. fun-define-follow{code} -> ( params{type fun} ) code-block{fun} -7. params{.create} -> param-list{fun} - {.create} | empty -8. param-list -> param{fun} param-follow{fun} -9. param-follow -> , param{fun} param-follow{fun} - | empty -10. param -> type ID array-subscript -11. array-subscript{type} -> [ ] - {type} | empty -12. code-block{code} -> { local-define-list{fun} code-list{fun} } -13. local-define-list -> local-var-define{fun} local-define-list{fun} - | empty -14. local-var-define -> type ID var-define-follow -15. code-list{code} -> code{fun} code-list{fun} - | empty -16. code{code} -> normal-statement{fun} - | selection-statement{fun} - | iteration-statement{fun} - | return-statement{fun} -17. normal-statement -> ; - | ID normal-statement-follow{fun id} -18. normal-statement-follow{code} -> var-follow{fun} = expression{fun} ; - {code} | call-follow{fun id} ; -19. call-follow{code} -> ( call-params{fun id} ) -20. call-params{code} -> call-param-list{fun} - | empty -21. call-param-list{num code} -> expression{fun} call-param-follow{fun} -22. call-param-follow{num code names} -> , expression{fun} call-param-follow{fun} - | empty -23. selection-statement{code} -> if ( expression{fun} ) { code-list{fun} } selection-follow{fun} -24. selection-follow{code} -> else { code-list{fun} } - {code} | empty -25. iteration-statement -> while ( expression{fun} ) iteration-follow{fun} -26. iteration-follow{code} -> { code-list{fun} } - {code} | code{fun} -27. return-statement{code} -> return return-follow{fun} -28. return-follow -> ; - | expression{fun} ; -29. var-follow{code name type} -> [ expression{fun} ] - {type} | empty -30. expression{code name bool} -> additive-expr{fun} expression-follow{fun} -31. expression-follow{bool code op name} -> rel-op additive-expr{fun} - {bool} | empty -32. rel-op{op} -> <= - | < - | > - | >= - | == - | != -33. additive-expr{name code} -> term{fun} additive-expr-follow{fun} -34. additive-expr-follow{add op code name} -> add-op term{fun} additive-expr-follow{fun} - {add} | empty -35. add-op{op} -> + - | - -36. term{name code} -> factor{fun} term-follow{fun} -37. term-follow{mul op code name} -> mul-op factor{fun} term-follow{fun} - {mul} | empty -38. mul-op{op} -> * - | / - | % -39. factor{name code} -> ( expression{fun} ) - | ID id-factor-follow{id fun} - | NUM -40. id-factor-follow -> var-follow{fun} - | ( args{fun} ) -41. args{code num} -> arg-list{fun} - | empty -42. arg-list{code num} -> expression{fun} arg-list-follow{fun} -43. arg-list-follow{code num names} -> , expression{fun} arg-list-follow{fun} - | empty -""" - - # 定义一个符号表池,每次调用函数的时候使用深拷贝从这里取局部变量表 symbol_table_pool = SymbolTablePool() @@ -389,6 +304,8 @@ class SemanticRuleFactory: return IterationStatement48E(node) # 49 + if rule_key == 'ReturnStatement49C1': + return ReturnStatement49C1(node) if rule_key == 'ReturnStatement49E': return ReturnStatement49E(node) @@ -397,6 +314,8 @@ class SemanticRuleFactory: return ReturnFollow50E(node) # 51 + if rule_key == 'ReturnFollow51C0': + return ReturnFollow51C0(node) if rule_key == 'ReturnFollow51E': return ReturnFollow51E(node) @@ -1481,6 +1400,13 @@ class IterationStatement48E(SemanticRule): node.code.append(f"(goto, _, _, {judge_block})") node.code.append(f"(block, _, _, {next_block})") +class ReturnStatement49C1(SemanticRule): + def execute(self): + return self.__rule(self.node) + + def __rule(self, node): + node.fun = node.parent.fun + class ReturnStatement49E(SemanticRule): def execute(self): self.__rule(self.node) @@ -1496,6 +1422,13 @@ class ReturnFollow50E(SemanticRule): def __rule(self, node): node.code.append("(return, _, _, _)") +class ReturnFollow51C0(SemanticRule): + def execute(self): + self.__rule(self.node) + + def __rule(self, node): + node.fun = node.parent.fun + class ReturnFollow51E(SemanticRule): def execute(self): @@ -1862,6 +1795,7 @@ class IdFactorFollow74E(SemanticRule): self.__rule(self.node) def __rule(self, node): + if symbol_table_pool.query(node.fun).exist(node.id): if node.children[0].type == "var": node.name = node.id @@ -1949,9 +1883,9 @@ class ArgList78E(SemanticRule): node.code.append(c) for c in node.children[1].code: node.code.append(c) - node.code.append("(param, _, _, )" + node.children[0].name) + node.code.append(f"(param, _, _, {node.children[0].name})") for name in node.children[1].names: - node.code.append("(param, _, _, )" + name) + node.code.append(f"(param, _, _, {name})") class ArgListFollow79C1(SemanticRule): def execute(self): diff --git a/syntax/rule.py b/syntax/rule.py index 8c2101b..bd695cf 100644 --- a/syntax/rule.py +++ b/syntax/rule.py @@ -552,7 +552,7 @@ productions = [ ), # 49 Production('return-statement', ['return', 'return-follow'], - None, [None, None], "ReturnStatement49E", + None, [None, 'ReturnStatement49C1'], "ReturnStatement49E", ), # 50 Production('return-follow', ['semicolon'], @@ -560,7 +560,7 @@ productions = [ ), # 51 Production('return-follow', ['exp', 'semicolon'], - None, [None, None], 'ReturnFollow51E', + None, ['ReturnFollow51C0', None], 'ReturnFollow51E', ), # 52 Production('exp', ['additive-expr', 'exp-follow'], @@ -648,7 +648,7 @@ productions = [ None, [None, 'ArgListFollow79C1', 'ArgListFollow79C2'], 'ArgListFollow79E'), # 80 Production('arg-list-follow', [], - None, [], 'ArgListFollowE'), + None, [], 'ArgListFollow80E'), # 81 Production('arraylist-with-num', [], diff --git a/test.c b/test.c deleted file mode 100644 index 33372d9..0000000 --- a/test.c +++ /dev/null @@ -1,18 +0,0 @@ -/* A program to perform Euclid s Algorithm to compute gcd. */ -int gcd(int u, int v) { - if (v == 0) { - return u; - } else { - return gcd(v, u-u/v*v); - } - /* u-u/v*v* == u mod v */ -} - -void main() { - int x; - int y; - x = input(); - y = input(); - output(gcd(x, y)); - return; -} diff --git a/test1.c b/test1.hy similarity index 58% rename from test1.c rename to test1.hy index ab5dad4..b53ce95 100644 --- a/test1.c +++ b/test1.hy @@ -1,17 +1,18 @@ -/*test1:斐波那契数列(控制流 + 函数调用)*/ -int fib(int n) { - if (n < 1){ - return n; - } else { - return fib(n - 1) + fib(n - 2); - } -} - -int main() { - int y; - int x; - x = 5 * 2 + 2; - a = 2 == 2; - x = fib(6); - return x; -} +/*test1:斐波那契数列(控制流 + 函数调用)*/ +fn fib(n:i32) -> i32 { + if n < 1 { + return n; + } else { + return fib(n - 1) + fib(n - 2); + } +} + +fn main() { + i32 x; + i32 y; + x = 5 * 2 + 2; + a = 2 == 2; + x = fib(6); + return x; +} + diff --git a/test2.c b/test2.c deleted file mode 100644 index 3cb5e90..0000000 --- a/test2.c +++ /dev/null @@ -1,14 +0,0 @@ -/* test2:阶乘计算(while 循环 + 局部变量)*/ -int fact(int n) { - int result; - result = 1; - while (n > 0) { - result = result * n; - n = n - 1; - } - return result; -} - -int main() { - return fact(5); -} diff --git a/test2.hy b/test2.hy new file mode 100644 index 0000000..c2d23fc --- /dev/null +++ b/test2.hy @@ -0,0 +1,16 @@ +// test2:阶乘计算(while 循环 + 局部变量) + +fn fact(n: i32) { + i32 result; + result = 1; + while n > 0 { + result = result * n; + n = n - 1; + } + + return result; +} + +fn main() { + return fact(5); +} \ No newline at end of file diff --git a/test3.c b/test3.c deleted file mode 100644 index 7fa6b6c..0000000 --- a/test3.c +++ /dev/null @@ -1,21 +0,0 @@ -/* test3:多函数协作(函数调用 + 全局变量)*/ -int a; -int b; - -int sum() { - return a + b; -} - -int product() { - return a * b; -} - -int main() { - int s; - int p; - a = 3; - b = 4; - s = sum(); - p = product(); - return s + p; -} diff --git a/test3.hy b/test3.hy new file mode 100644 index 0000000..fe7f307 --- /dev/null +++ b/test3.hy @@ -0,0 +1,22 @@ +// test3:多函数协作(函数调用 + 全局变量) +i32 a; +i32 b; + +fn sum() { + return a + b; +} + +fn product() { + return a * b; +} + +fn main() { + i32 s; + i32 p; + a = 3; + b = 4; + // s = sum(a); + s = sum(); + p = product(); + return s + p; +} \ No newline at end of file diff --git a/test4.c b/test4.c deleted file mode 100644 index 84df68b..0000000 --- a/test4.c +++ /dev/null @@ -1,19 +0,0 @@ -/* test4:嵌套 if 判断(复杂控制流)*/ -int max(int x, int y) { - if (x > y) { - return x; - } - else { - return y; - } -} - -int main() { - int a; - int b; - int c; - a = 10; - b = 20; - c = max(a, b); - return c; -} diff --git a/test4.hy b/test4.hy new file mode 100644 index 0000000..adb7108 --- /dev/null +++ b/test4.hy @@ -0,0 +1,20 @@ +// test4:嵌套 if 判断(复杂控制流) + +fn max(x: i32, y: i32) -> i32 { + if x > y { + return x; + } else { + return y; + } +} + +fn main() { + i32 a; + i32 b; + i32 c; + + a = 10; + b = 20; + c = max(a, b); + return c; +} \ No newline at end of file diff --git a/test5.c b/test5.c deleted file mode 100644 index 29ccedf..0000000 --- a/test5.c +++ /dev/null @@ -1,29 +0,0 @@ -/* test5:冒泡排序(数组访问模拟)*/ -int swap(int i, int j) { - int temp; - temp = i; - i = j; - j = temp; - return 0; -} - -int main() { - int a; - int b; - int c; - int d; - int e; - a = 5; - b = 3; - c = 8; - d = 1; - e = 9; - - /* 冒泡排序模拟 */ - if (a > b) { swap(a, b); } - if (b > c) { swap(b, c); } - if (c > d) { swap(c, d); } - if (d > e) { swap(d, e); } - - return e; -} diff --git a/test5.hy b/test5.hy new file mode 100644 index 0000000..3128488 --- /dev/null +++ b/test5.hy @@ -0,0 +1,20 @@ +// while + if +fn is_prime(n:i32) -> i32 { + i32 i; + if n <= 1 { + return 0; + } + + i = 2; + while i * i <= n { + if n % i == 0 { + return 0; + } + i = i + 1; + } + return 1; +} + +fn main() { + return is_prime(17); +} \ No newline at end of file diff --git a/test6.c b/test6.c deleted file mode 100644 index fcc98b9..0000000 --- a/test6.c +++ /dev/null @@ -1,13 +0,0 @@ -/* test6:逻辑表达式优先级测试 */ -int main() { - int a; - int b; - int c; - a = 1; - b = 2; - c = 3; - - int result; - result = a == 1 && b < c || c != 4; - return result; -} \ No newline at end of file diff --git a/test8.c b/test6.hy similarity index 60% rename from test8.c rename to test6.hy index cfc36a3..e4630bf 100644 --- a/test8.c +++ b/test6.hy @@ -1,19 +1,19 @@ -/* test8:带错误的语法测试(用于验证报错机制)*/ -int main() { - int x; - x = ; /* 错误:缺少右值 */ - return x; -} - -int main1() { - int x; - x == 10; /* 错误:应为赋值 = */ - return x; -} - -int main2() { - int x; - if (x) /* 错误:if 条件必须是整型表达式 */ - return 1; - return 0; -} +/* test6:带错误的语法测试(用于验证报错机制)*/ +fn main() { + i32 x; + x = ; /* 错误:缺少右值 */ + return x; +} + +fn main1() { + int x; + x == 10; /* 错误:应为赋值 = */ + return x; +} + +fn main2() { + i32 x; + if (x) /* 错误:if 条件必须是整型表达式 */ + return 1; + return 0; +} diff --git a/test7.c b/test7.c deleted file mode 100644 index e6a3328..0000000 --- a/test7.c +++ /dev/null @@ -1,19 +0,0 @@ -/* test7:嵌套循环(while + if)*/ -int is_prime(int n) { - int i; - if (n <= 1) { - return 0; - } - i = 2; - while (i * i <= n) { - if (n % i == 0) { - return 0; - } - i = i + 1; - } - return 1; -} - -int main() { - return is_prime(17); -} diff --git a/test9.c b/test7.hy similarity index 100% rename from test9.c rename to test7.hy