diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 48a1652..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 John Kindem - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index 3e65be5..d8a47c2 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,208 @@ -# C(缩减版)语言编译器前端 -## 是什么 -NUAA 2017年编译原理课设,词法分析使用正则表达式,语法分析使用LL(1)文法分析器, -语义分析使用自上而下翻译,使用 Python 语言编写,面向配置化,稍加改造可以适用其他文法 +

Hydrogen 语言大纲

-## 怎么使用 +[toc] + +## 1. 语法文档 + +### 1.1 变量 + + +变量声明 + +```go +i32 f1; // 整型字变量默认为i32,支持自动类型转换 +f32 f2; + +i32[5] f3; // 数组声明 +f32[93] f4; ``` -git clone https://github.com/FlyAndNotDown/CSub-CompilerFrontend.git + +#### 支持的数值类型 + +| 实数类型 | 数组类型 | +| -------- | ------------ | +| i32 | i32[num-int] | +| f32 | f32[num-int] | + + + +### 1.2 注释 + +#### 单行注释 + +单行注释使用 `//` 开头,后面跟随注释内容。例如: + +``` +// 这是一个单行注释 ``` -在 PyCharm 中打开新建项目导入代码即可,Python 使用版本为 3 以上,请不要使用 Python2 运行该项目 -## 代码结构说明 -* main.py 编译器主程序 -* error.py 存放错误相关的类和代码 -* test.c 要编译的文件 -* lexical 词法分析 -* syntax 语法分析 -* semantic 语义分析 +#### 多行注释 -另外,三大分析中 rule.py 即是支持编译器的所有文法、词法、语义规则,加以改动即可面向一些其他的文法和语言使用 +多行注释使用 `/*` 开头,并以 `*/` 结束。例如: -## 关于 -NUAA 161520311 John Kindem +``` +/* +这是一个多行注释 +可以跨越多行 +*/ +``` + +### 1.3 控制结构 + +#### if 语法 + +``` +if condition { + // 当 condition 为 true 时执行的代码 +} else { + // 当 condition 为 false 时执行的代码 +} +``` + +condition 的类型必须是 bool + +可以使用 else 语法来检查多个条件,示例: + +``` +fn main() { + i32 type; + i32 foo; + + age = 32; + + if foo >= 60 { + a = 0; + + } else { + if foo >= 18 { + a = 1; + } else { + a = 2; + } + } +} +``` + +#### While 语法 + +`while` 语句用于循环执行代码块。Nature 语言中的 `for` 语句有三种主要形式:经典循环、条件循环。 + +- **经典循环** + +经典循环用于执行固定次数的循环。基本语法如下: + +``` +fn main() { + i32 a; + i32 sum; + a = 0; + sum = 0; + while a <= 100 { + sum = sum + a; + a = a + 1; + } +} +``` + +在这个示例中,循环从 `i = 1` 开始,每次循环 `i` 增加 1,直到 `i` 大于 100。 + +- 1.5 算术运算符 + +| 优先级 | 关键字 | 使用示例 | 说明 | +| ------ | ------ | -------------- | ---------------------- | +| 1 | () | (1 + 1) | (expr) | +| 2 | / | 1 / 2 | 除 | +| 2 | * | 1 * 2 | 乘 | +| 2 | % | 5 % 2 | 余数 | +| 3 | + | 1 + 1 | 加 | +| 3 | - | 1 - 1 | 减 | +| 4 | > | 1 > 2 | 大于 | +| 4 | >= | 1 >= 2 | 大于等于 | +| 4 | < | 1 < 2 | 小于 | +| 4 | <= | 1 <= 2 | 小于等于 | +| 4 | == | 1 == 2 | 等于 | +| 4 | != | 1 != 2 | 不等于 | + + +### 1.4 函数 + +函数声明语法如下 + +```` +fn 函数名(参数名:参数类型,....) -> 返回类型 { + ... +} +```` + +> 注意: -> 返回类型可以省略,省略后默认返回void +> +> 例子: + +``` +fn main() { + + return 0; +} +``` + + + + + + +## 2. 实现细节 + +### 2.1 符号表 +#### 全局变量表 + +| Name | Type | Width | Offset | +| ---- | ---- | ----- | ------ | +| g_a | i32 | 4 | 0 | +| | | | | + + + +#### 函数表 + +| Function Name | Return Type | Local Var Table | +| ------------- | ----------- | --------------- | +| main | void | main | + + + +#### 局部变量表 + +表名称:main + +| Name | Type | Width | Offset | Is Param | +| ---- | ----- | ----- | ------ | -------- | +| test | i32 | 4 | 0 | True | +| a | i32[] | 128 | 4 | False | +| | | | | | +| | | | | | + + + +### 2.2 四元式 + +1. **函数定义** + - 表示函数入口,例如:(fun, _, _, main)(定义主函数)。 +2. **赋值操作** + - 将常量或变量赋给临时变量或目标变量,例如: + - (=, 32, _, _v0)(常量赋值) + - (=, _v0, _, age)(变量赋值) + - (=, 0, _, _v18)(常量赋值给临时变量)。 +3. **比较操作** + - 包括大于等于 (>=) 和小于等于 (<=),生成布尔结果,例如: + - (>=, foo, _v1, _v2) + - (<=, foo, _v10, _v11) +4. **条件跳转** + - 根据条件判断跳转到指定基本块,例如:(if, _v3, goto, __b3)。 +5. **无条件跳转** + - 直接跳转到指定基本块,例如:(goto, _, _, __b5)。 +6. **基本块标记** + - 定义控制流中的基本块,例如:(block, _, _, __b3)。 +7. **算术操作** + - 执行加法运算,例如:(+, age, a, _v13)。 +8. **返回操作** + - **新增**:表示函数返回特定值,例如:(return, _, _, _v18)(返回临时变量 _v18 的值)。 diff --git a/lexical/rule.py b/lexical/rule.py index 08efa62..dab2052 100644 --- a/lexical/rule.py +++ b/lexical/rule.py @@ -13,10 +13,11 @@ token_type = [ 'fn', 'multiplication', 'division', - 'bigger', + 'yushu', 'bigger-equal', - 'smaller', 'smaller-equal', + 'bigger', + 'smaller', 'equal', 'not-equal', 'evaluate', @@ -66,6 +67,7 @@ regex_dict = { 'subtraction': r'-', 'multiplication': r'\*', 'division': r'/', + 'yushu': r'%', 'bigger': r'>', 'bigger-equal': r'>=', 'smaller': r'<', @@ -82,7 +84,7 @@ regex_dict = { 'right-bracket': r'\]', 'left-brace': r'\{', 'right-brace': r'\}', - 'id': r'[a-zA-Z][a-zA-Z]*', + 'id': r'[a-zA-Z][a-zA-Z_]*', 'float-num': r'\d+\.\d+[eE][+-]\d+|\d+\.\d+|\d+[eE][+-]\d+', 'int-num': r'[1-9][0-9]*|0', } \ No newline at end of file diff --git a/main.py b/main.py index 72cbec4..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() # 打印结果 @@ -35,7 +40,7 @@ if lexical_success: if syntax_success: print() print('语义分析结果:\t') - print('三地址代码:\t') + print('四元式代码:\t') i = -1 for code in syntax.get_result().root.code: i += 1 diff --git a/rule_back.py b/rule_back.py deleted file mode 100644 index b67b647..0000000 --- a/rule_back.py +++ /dev/null @@ -1,488 +0,0 @@ -class Sign: - """ - 符号 - """ - def __init__(self, sign_type, sign_str='', sign_line=-1): - """ - 构造 - :param sign_type: 符号的类型 - :param sign_str: 符号的内容(可以为空) - :param sign_line: 符号所在行数(可以为空) - """ - self.type = sign_type - self.str = sign_str - self.line = sign_line - - def is_terminal_sign(self): - """ - 是不是终结符 - :return: True/False - """ - if self.type == 'empty': - return True - else: - for i in terminal_sign_type: - if i == self.type: - return True - return False - - def is_non_terminal_sign(self): - """ - 是不是非终结符 - :return: True/False - """ - for i in non_terminal_sign_type: - if i == self.type: - return True - return False - - def is_empty_sign(self): - """ - 是不是空字 - :return: True/False - """ - return self.type == 'empty' - - -class Production: - """ - 产生式 - """ - def __init__(self, left_type, right_types, semantic_start, semantic_children, semantic_end): - """ - 产生式左边 - :param left_type: 产生式左边的符号类型 - :param right_types: 产生式右边的符号类型列表 - :param semantic_start: 语义操作关键字 - 开始 - :param semantic_children: 语义操作关键字 - 孩子 - :param semantic_end: 语义操作关键字 - 结束 - """ - self.left = Sign(left_type) - self.right = list() - for i in right_types: - self.right.append(Sign(i)) - - # 调试用的 - self.str = self.left.type + ' ->' - for i in self.right: - self.str += ' ' + i.type - - # 语义操作关键字 - self.semantic_start = semantic_start - self.semantic_children = list() - for c in semantic_children: - self.semantic_children.append(c) - self.semantic_end = semantic_end - - -""" -1. program -> define-list -2. define-list -> define define-list - | empty -3. define -> type ID define-type -4. define-type -> var-define-follow - | fun-define-follow -5. var-define-follow -> ; - | [ NUM ] ; -6. type -> int - | void -7. fun-define-follow -> ( params ) code-block -8. params -> param-list - | empty -9. param-list -> param param-follow -10. param-follow -> , param param-follow - | empty -11. param -> type ID array-subscript -12. array-subscript -> [ ] - | empty -13. code-block -> { local-define-list code-list } -14. local-define-list -> local-var-define local-define-list - | empty -15. local-var-define -> type ID var-define-follow -16. code-list -> code code-list - | empty -17. code -> normal-statement - | selection-statement - | iteration-statement - | return-statement -18. normal-statement -> ; - | ID normal-statement-follow -19. normal-statement-follow -> var-follow = expression ; - | call-follow ; -20. call-follow -> ( call-params ) -21. call-params -> call-param-list - | empty -22. call-param-list -> expression call-param-follow -23. call-param-follow -> , expression call-param-follow - | empty -24. selection-statement -> if ( expression ) { code-list } selection-follow -25. selection-follow -> else { code-list } - | empty -26. iteration-statement -> while ( expression ) iteration-follow -27. iteration-follow -> { code-list } - | code -28. return-statement -> return return-follow -29. return-follow -> ; - | expression ; -30. var-follow -> [ expression ] - | empty -31. expression -> additive-expr expression-follow -32. expression-follow -> rel-op additive-expr - | empty -33. rel-op -> <= - | < - | > - | >= - | == - | != -34. additive-expr -> term additive-expr-follow -35. additive-expr-follow -> add-op term additive-expr-follow - | empty -36. add-op -> + - | - -37. term -> factor term-follow -38. term-follow -> mul-op factor term-follow - | empty -39. mul-op -> * - | / - | % -40. factor -> ( expression ) - | ID id-factor-follow | NUM -41. id-factor-follow -> var-follow - | ( args ) -42. args -> arg-list - | empty -43. arg-list -> expression arg-list-follow -44. arg-list-follow -> , expression arg-list-follow - | empty -""" - - -# 所有终结符的类型 -# 终结符是文法中不能再被展开的基本单元,直接来源于词法分析器的 token.type。 -# 这些类型用于语法分析过程中与输入 token 的类型进行匹配。 -terminal_sign_type = [ - 'else', # else 关键字 - 'if', # if 关键字 - 'int', # int 关键字,表示整型变量 - 'return', # return 关键字,函数返回语句 - 'void', # void 关键字,表示无返回值或无参数 - 'while', # while 关键字,用于循环结构 - - 'addition', # 加法运算符 '+' - 'subtraction', # 减法运算符 '-' - 'multiplication', # 乘法运算符 '*' - 'division', # 除法运算符 '/' - 'remainder', # 取余运算符 '%' - - 'bigger', # 大于操作符 '>' - 'bigger-equal', # 大于等于操作符 '>=' - 'smaller', # 小于操作符 '<' - 'smaller-equal', # 小于等于操作符 '<=' - 'equal', # 等于比较操作符 '==' - 'not-equal', # 不等于比较操作符 '!=' - 'evaluate', # 赋值操作符 '=' - - 'semicolon', # 分号 ';' - 'comma', # 逗号 ',' - 'left-parentheses', # 左圆括号 '(' - 'right-parentheses', # 右圆括号 ')' - 'left-bracket', # 左方括号 '[' - 'right-bracket', # 右方括号 ']' - 'left-brace', # 左花括号 '{' - 'right-brace', # 右花括号 '}' - - 'id', # 标识符,例如变量名、函数名 - 'num', # 数字常量,例如整数 - - # 特殊标记:结束符 - # 注意:不要在 'pound' 之前添加非终结符类型!这是语法分析器内部使用的结束标志。 - 'pound' # 输入结束标志 '#' -] - -# 所有非终结符的类型 -# 非终结符是文法中可以进一步被展开的语法成分,通常由产生式定义。 -# 每个非终结符会在语法分析过程中被替换成终结符或其它非终结符组成的序列。 -non_terminal_sign_type = [ - 'program', # 程序整体结构 - 'define-list', # 定义列表(全局变量和函数定义) - 'define', # 单个定义(变量或函数) - 'define-type', # 定义类型(变量定义或函数定义) - - 'var-define-follow', # 变量定义后续部分(如分号或数组声明) - 'type', # 类型(int 或 void) - 'fun-define-follow', # 函数定义后续部分(参数列表和函数体) - - 'params', # 参数列表 - 'param-list', # 参数列表主体 - 'param-follow', # 参数后续部分(可能包含更多参数) - 'param', # 单个参数定义 - - 'array-subscript', # 数组下标部分 '[ ]' - 'code-block', # 代码块 '{ ... }' - 'local-define-list', # 局部变量定义列表 - 'local-var-define', # 局部变量定义 - 'code-list', # 代码语句列表 - 'code', # 单条语句(控制结构、表达式等) - - 'normal-statement', # 正常语句(赋值、声明等) - 'normal-statement-follow', # 正常语句后续部分(赋值或函数调用) - - 'call-follow', # 函数调用后续部分(参数列表) - 'call-params', # 函数调用参数列表 - 'call-param-list', # 函数调用参数主体 - 'call-param-follow', # 函数调用后续参数处理 - - 'selection-statement', # 选择语句(if) - 'selection-follow', # else 分支 - - 'iteration-statement', # 循环语句(while) - 'iteration-follow', # 循环体(可能是代码块或单条语句) - - 'return-statement', # 返回语句 - 'return-follow', # 返回值部分 - - # 'eval-statement', # 表达式语句(已被注释) - # 'var', # 变量引用(已被注释) - - 'var-follow', # 变量后续部分(数组访问 [expr]) - 'expression', # 表达式 - 'expression-follow', # 表达式后续部分(关系运算符 + 表达式) - - 'rel-op', # 关系运算符(<=, <, >, >=, ==, !=) - - 'additive-expr', # 加减表达式 - 'additive-expr-follow', # 加减表达式的递归部分 - - 'add-op', # 加减运算符 '+' 或 '-' - - 'term', # 项(乘除操作单位) - 'term-follow', # 项的递归部分(乘除表达式) - - 'mul-op', # 乘除余运算符 '*' 或 '/' 或 '%' - - 'factor', # 因子(基本表达式单元) - 'id-factor-follow', # 标识符后的扩展(可能是数组或函数调用) - - 'args', # 函数调用参数 - 'arg-list', # 参数列表 - 'arg-list-follow', # 参数后续部分(多个参数间的递归) -] - -# 文法产生式 -productions = [ - # 0 - Production('program', ['define-list'], - 'Program0S', [None], 'Program0E'), - # 1 - Production('define-list', ['define', 'define-list'], - None, [None, None], 'DefineList0E'), - Production('define-list', [], - None, [], 'DefineList1E'), - # 2 - Production('define', ['type', 'id', 'define-type'], - None, [None, None, 'Define0C2'], 'Define0E'), - # 3 - Production('define-type', ['var-define-follow'], - 'DefineType0S', ['DefineType0C0'], 'DefineType0E'), - Production('define-type', ['fun-define-follow'], - 'DefineType1S', ['DefineType1C0'], 'DefineType1E'), - # 4 - Production('var-define-follow', ['semicolon'], - None, [None], 'VarDefineFollow0E'), - Production('var-define-follow', ['left-bracket', 'num', 'right-bracket', 'semicolon'], - None, [None, None, None, None], 'VarDefineFollow1E'), - # 5 - Production('type', ['int'], - 'Type0S', [None], None), - Production('type', ['void'], - 'Type1S', [None], None), - # 6 - Production('fun-define-follow', ['left-parentheses', 'params', 'right-parentheses', 'code-block'], - None, [None, 'FunDefineFollow0C1', None, 'FunDefineFollow0C3'], 'FunDefineFollow0E'), - # 7 - Production('params', ['param-list'], - 'Params0S', ['Params0C0'], None), - Production('params', [], - 'Params1S', [], None), - # 8 - Production('param-list', ['param', 'param-follow'], - None, ['ParamList0C0', 'ParamList0C1'], None), - # 9 - Production('param-follow', ['comma', 'param', 'param-follow'], - None, [None, 'ParamFollow0C1', 'ParamFollow0C2'], None), - Production('param-follow', [], - None, [], None), - # 10 - Production('param', ['type', 'id', 'array-subscript'], - None, [None, None, None], 'Param0E'), - # 11 - Production('array-subscript', ['left-bracket', 'right-bracket'], - 'ArraySubscript0S', [None, None], None), - Production('array-subscript', [], - 'ArraySubscript1S', [], None), - # 12 - Production('code-block', ['left-brace', 'local-define-list', 'code-list', 'right-brace'], - None, [None, 'CodeBlock0C1', 'CodeBlock0C2', None], 'CodeBlock0E'), - # 13 - Production('local-define-list', ['local-var-define', 'local-define-list'], - None, ['LocalDefineList0C0', 'LocalDefineList0C1'], None), - Production('local-define-list', [], - None, [], None), - # 14 - Production('local-var-define', ['type', 'id', 'var-define-follow'], - None, [None, None, None], 'LocalVarDefine0E'), - # 15 - Production('code-list', ['code', 'code-list'], - None, ['CodeList0C0', 'CodeList0C1'], 'CodeList0E'), - Production('code-list', [], - None, [], 'CodeList1E'), - # 16 - Production('code', ['normal-statement'], - None, ['Code0C0'], 'Code0E'), - Production('code', ['selection-statement'], - None, ['Code1C0'], 'Code1E'), - Production('code', ['iteration-statement'], - None, ['Code2C0'], 'Code2E'), - Production('code', ['return-statement'], - None, ['Code3C0'], 'Code3E'), - # Production('normal-statement', ['eval-statement', 'semicolon']), - # Production('normal-statement', ['semicolon']), - # 17 - Production('normal-statement', ['semicolon'], - None, [None], 'NormalStatement0E'), - Production('normal-statement', ['id', 'normal-statement-follow'], - None, [None, 'NormalStatement1C1'], 'NormalStatement1E'), - # 18 - Production('normal-statement-follow', ['var-follow', 'evaluate', 'expression', 'semicolon'], - None, ['NormalStatementFollow0C0', None, 'NormalStatementFollow0C2', None], 'NormalStatementFollow0E'), - Production('normal-statement-follow', ['call-follow', 'semicolon'], - None, ['NormalStatementFollow1C0', None], 'NormalStatementFollow1E'), - # 19 - Production('call-follow', ['left-parentheses', 'call-params', 'right-parentheses'], - None, [None, 'CallFollow0C1', None], 'CallFollow0E'), - # 20 - Production('call-params', ['call-param-list'], - None, ['CallParams0C0'], 'CallParams0E'), - Production('call-params', [], - None, [], 'CallParams1E'), - # 21 - Production('call-param-list', ['expression', 'call-param-follow'], - None, ['CallParamList0C0', 'CallParamList0C1'], 'CallParamList0E'), - # 22 - Production('call-param-follow', ['comma', 'expression', 'call-param-follow'], - None, [None, 'CallParamFollow0C1', 'CallParamFollow0C2'], 'CallParamFollow0E'), - Production('call-param-follow', [], - None, [], 'CallParamFollow1E'), - # 23 - Production('selection-statement', - ['if', 'left-parentheses', 'expression', 'right-parentheses', 'left-brace', - 'code-list', 'right-brace', 'selection-follow'], - None, [None, None, 'SelectionStatement0C2', None, None, 'SelectionStatement0C5', - None, 'SelectionStatement0C5'], 'SelectionStatement0E'), - # 24 - Production('selection-follow', ['else', 'left-brace', 'code-list', 'right-brace'], - None, [None, None, 'SelectionFollow0C2', None], 'SelectionFollow0E'), - Production('selection-follow', [], - None, [], 'SelectionFollow1E'), - # 25 - Production('iteration-statement', ['while', 'left-parentheses', 'expression', - 'right-parentheses', 'iteration-follow'], - None, [None, None, 'IterationStatement0C2', None, 'IterationStatement0C4'], 'IterationStatement0E'), - # 26 - Production('iteration-follow', ['left-brace', 'code-list', 'right-brace'], - None, [None, 'IterationFollow0C1', None], 'IterationFollow0E'), - Production('iteration-follow', ['code'], - None, ['IterationFollow1C0'], 'IterationFollow1E'), - # 27 - Production('return-statement', ['return', 'return-follow'], - None, [None, 'ReturnStatement0C1'], 'ReturnStatement0E'), - # 28 - Production('return-follow', ['semicolon'], - None, [None], 'ReturnFollow0E'), - Production('return-follow', ['expression', 'semicolon'], - None, ['ReturnFollow1C0', None], 'ReturnFollow1E'), - # Production('eval-statement', ['var', 'evaluate', 'expression']), - # Production('var', ['id', 'var-follow']), - # 29 - Production('var-follow', ['left-bracket', 'expression', 'right-bracket'], - None, [None, 'VarFollow0C1', None], 'VarFollow0E'), - Production('var-follow', [], - None, [], 'VarFollow1E'), - # 30 - Production('expression', ['additive-expr', 'expression-follow'], - None, ['Expression0C0', 'Expression0C1'], 'Expression0E'), - # 31 - Production('expression-follow', ['rel-op', 'additive-expr'], - None, [None, 'ExpressionFollow0C1'], 'ExpressionFollow0E'), - Production('expression-follow', [], - None, [], 'ExpressionFollow1E'), - # 32 - Production('rel-op', ['smaller-equal'], - None, [None], 'RelOp0E'), - Production('rel-op', ['smaller'], - None, [None], 'RelOp1E'), - Production('rel-op', ['bigger'], - None, [None], 'RelOp2E'), - Production('rel-op', ['bigger-equal'], - None, [None], 'RelOp3E'), - Production('rel-op', ['equal'], - None, [None], 'RelOp4E'), - Production('rel-op', ['not-equal'], - None, [None], 'RelOp5E'), - # 33 - Production('additive-expr', ['term', 'additive-expr-follow'], - None, ['AdditiveExpr0C0', 'AdditiveExpr0C1'], 'AdditiveExpr0E'), - # 34 - Production('additive-expr-follow', ['add-op', 'term', 'additive-expr-follow'], - None, [None, 'AdditiveExprFollow0C1', 'AdditiveExprFollow0C2'], 'AdditiveExprFollow0E'), - Production('additive-expr-follow', [], - None, [], 'AdditiveExprFollow1E'), - # 35 - Production('add-op', ['addition'], - None, [None], 'AddOp0E'), - Production('add-op', ['subtraction'], - None, [None], 'AddOp1E'), - # 36 - Production('term', ['factor', 'term-follow'], - None, ['Term0C0', 'Term0C1'], 'Term0E'), - # 37 - Production('term-follow', ['mul-op', 'factor', 'term-follow'], - None, [None, 'TermFollow0C1', 'TermFollow0C2'], 'TermFollow0E'), - Production('term-follow', [], - None, [], None), - # 38 - Production('mul-op', ['multiplication'], - None, [None], 'MulOp0E'), - Production('mul-op', ['division'], - None, [None], 'MulOp1E'), - Production('mul-op', ['remainder'], - None, [None], 'MulOp2E'), - # 39 - Production('factor', ['left-parentheses', 'expression', 'right-parentheses'], - None, [None, 'Factor0C1', None], 'Factor0E'), - Production('factor', ['id', 'id-factor-follow'], - None, [None, 'Factor1C1'], 'Factor1E'), - Production('factor', ['num'], - None, [None], 'Factor2E'), - # 40 - Production('id-factor-follow', ['var-follow'], - None, [None], 'IdFactorFollow0E'), - Production('id-factor-follow', ['left-parentheses', 'args', 'right-parentheses'], - None, [None, 'IdFactorFollow1C1', None], 'IdFactorFollow1E'), - # 41 - Production('args', ['arg-list'], - None, ['Args0C0'], 'Args0E'), - Production('args', [], - None, [], 'Args1E'), - # 42 - Production('arg-list', ['expression', 'arg-list-follow'], - None, ['ArgList0C0', 'ArgList0C1'], 'ArgList0E'), - Production('arg-list-follow', ['comma', 'expression', 'arg-list-follow'], - None, [None, 'ArgListFollow0C1', 'ArgListFollow0C2'], 'ArgListFollow0E'), - Production('arg-list-follow', [], - None, [], 'ArgListFollow1E') -] - -# 文法开始符号 -grammar_start = Sign('program') \ No newline at end of file diff --git a/semantic/rule.py b/semantic/rule.py index 7edee65..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) @@ -556,8 +475,17 @@ class SemanticRuleFactory: # 82 if rule_key == 'ArrayListWithNum82E': return ArrayListWithNum82E(node) + + + # 84 + if rule_key == 'MulOp84E': + return MulOp84E(node) return None + return None + + + # S 产生式开始 # E 产生式结束 # CN 产生式第N个元素应用之后 @@ -1283,11 +1211,11 @@ class CallFollow39E(SemanticRule): def __rule(self, node): if symbol_table_pool.fun_table.exist(node.id): if node.children[1].num != symbol_table_pool.query(node.id).get_params_num(): - self.errors.append(f"错误 : 调用函数{node.id}的参数与实际参数不匹配") + self.errors.append(SemanticError(f"错误 : 调用函数{node.id}的参数与实际参数不匹配")) for c in node.children[1].code: node.code.append(c) else: - self.errors.append(f"错误 : 调用函数{node.id}不存在") + self.errors.append(SemanticError(f"错误 : 调用函数{node.id}不存在")) @@ -1397,23 +1325,25 @@ class SelectionStatement45E(SemanticRule): else: for c in node.children[1].code: node.code.append(c) - if_block = get_temp_block_name() - else_block = get_temp_block_name() - next_block = get_temp_block_name() - node.code.append(f"(if, {node.children[1].name}, goto, {if_block})") + if_block = get_temp_block_name() + else_block = get_temp_block_name() + next_block = get_temp_block_name() - node.code.append(f"(block, _, _, {if_block})") - for c in node.children[3].code: - node.code.append(c) - node.code.append(f"goto, _, _, {next_block}") - node.code.append(f"(block, _, _, {else_block})") - for c in node.children[5].code: - node.code.append(c) - node.code.append(f"(goto, _, _, {next_block})") + node.code.append(f"(if, {node.children[1].name}, goto, {if_block})") - node.code.append(f"(block, _, _, {next_block})") + node.code.append(f"(block, _, _, {if_block})") + for c in node.children[3].code: + node.code.append(c) + node.code.append(f"(goto, _, _, {next_block})") + + node.code.append(f"(block, _, _, {else_block})") + for c in node.children[5].code: + node.code.append(c) + node.code.append(f"(goto, _, _, {next_block})") + + node.code.append(f"(block, _, _, {next_block})") class SelectionFollow46C2(SemanticRule): def execute(self): @@ -1462,7 +1392,7 @@ class IterationStatement48E(SemanticRule): node.code.append(f"(block, _, _, {judge_block})") for c in node.children[1].code: node.code.append(c) - node.code.append(f"(if, {node.children[2].name}, goto, {iteration_block})") + node.code.append(f"(if, {node.children[1].name}, goto, {iteration_block})") node.code.append(f"(goto, _, _, {next_block})") node.code.append(f"(block, _, _, {iteration_block})") for c in node.children[3].code: @@ -1470,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) @@ -1485,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): @@ -1502,16 +1446,15 @@ class Exp52C0(SemanticRule): self.__rule(self.node) def __rule(self, node): - self.fun = node.parent.fun - print("52C0") - print(self.fun) + node.fun = node.parent.fun + class Exp52C1(SemanticRule): def execute(self): self.__rule(self.node) def __rule(self, node): - self.fun = node.parent.fun + node.fun = node.parent.fun class Exp52E(SemanticRule): def execute(self): @@ -1613,8 +1556,7 @@ class AdditiveExpr61C0(SemanticRule): def __rule(self, node): node.fun = node.parent.fun - print("61C0") - print(node.parent.fun) + class AdditiveExpr61C1(SemanticRule): def execute(self): @@ -1622,8 +1564,6 @@ class AdditiveExpr61C1(SemanticRule): def __rule(self, node): node.fun = node.parent.fun - print("61C1") - print(node.parent.fun) class AdditiveExpr61E(SemanticRule): @@ -1716,8 +1656,7 @@ class Term66C0(SemanticRule): def __rule(self, node): node.fun = node.parent.fun - print("66C0") - print(node.fun) + class Term66C1(SemanticRule): def execute(self): @@ -1832,8 +1771,7 @@ class Factor72C1(SemanticRule): def __rule(self, node): node.id = node.get_pre_brother(1).lexical node.fun = node.parent.fun - print("72C1") - print(node.fun) + class Factor72E(SemanticRule): def execute(self): @@ -1857,8 +1795,7 @@ class IdFactorFollow74E(SemanticRule): self.__rule(self.node) def __rule(self, node): - print("74E") - print(node.fun) + if symbol_table_pool.query(node.fun).exist(node.id): if node.children[0].type == "var": node.name = node.id @@ -1867,10 +1804,10 @@ class IdFactorFollow74E(SemanticRule): node.name = get_temp_var_name() for c in node.children[0].code: node.code.append(c) - node.code.append("(=[], " + node.id, + ", " + node.children[0].name + ", " + node.name) + node.code.append(f"(=[], {node.id}, {node.children[0].name}, {node.name})") else: - self.errors.append('变量' + node.id + '未定义') + self.errors.append(SemanticError('变量' + node.id + '未定义')) class IdFactorFollow75C1(SemanticRule): def execute(self): @@ -1886,7 +1823,7 @@ class IdFactorFollow75E(SemanticRule): def __rule(self, node): if symbol_table_pool.fun_table.exist(node.id): if node.children[1].num != symbol_table_pool.query(node.id).get_params_num(): - self.errors.append('调用函数' + node.id + ', 参数数量不匹配') + self.errors.append(SemanticError('调用函数' + node.id + ', 参数数量不匹配')) else: for c in node.children[1].code: @@ -1896,7 +1833,7 @@ class IdFactorFollow75E(SemanticRule): node.code.append('(=, result, _, ' + node.name + ')') else: - self.errors.append('函数' + node.id + '未定义') + self.errors.append(SemanticError('函数' + node.id + '未定义')) class Args76C0(SemanticRule): def execute(self): @@ -1946,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): @@ -1994,3 +1931,11 @@ class Factor83E(SemanticRule): def __rule(self, node): node.name = get_temp_var_name() node.code.append("(=, " + node.children[0].lexical, +", _, ", node.name) + + +class MulOp84E(SemanticRule): + def execute(self): + self.__rule(self.node) + + def __rule(self, node): + node.op = node.children[0].lexical \ No newline at end of file diff --git a/semantic/symbol.py b/semantic/symbol.py index db3c46b..2b2eb78 100644 --- a/semantic/symbol.py +++ b/semantic/symbol.py @@ -1,3 +1,5 @@ +from prettytable import PrettyTable + class Symbol: """ 符号基类 @@ -86,21 +88,21 @@ class SymbolTablePool: self.fun_table = FunTable() # 添加 output 和 input 的支持 - self.local_var_tables.append( - LocalVarTable('input', self.global_var_table) - ) - self.local_var_tables.append( - LocalVarTable('output', self.global_var_table) - ) - self.query('output').append( - LocalVar('output_name', 'i32', 4, True) - ) - self.fun_table.append( - Fun('input', 'i32', self.query('input')) - ) - self.fun_table.append( - Fun('output', 'void', self.query('output')) - ) + # self.local_var_tables.append( + # LocalVarTable('input', self.global_var_table) + # ) + # self.local_var_tables.append( + # LocalVarTable('output', self.global_var_table) + # ) + # self.query('output').append( + # LocalVar('output_name', 'i32', 4, True) + # ) + # self.fun_table.append( + # Fun('input', 'i32', self.query('input')) + # ) + # self.fun_table.append( + # Fun('output', 'void', self.query('output')) + # ) def change_fun_type(self, fun_name, type): """ @@ -130,21 +132,48 @@ class SymbolTablePool: self.local_var_tables.append(local_var_table) def debug(self): + # Global Variable Table print("Global Variable Table:") + table = PrettyTable() + table.field_names = ["Name", "Type", "Width", "Offset"] for symbol in self.global_var_table._table: - print(vars(symbol)) + table.add_row([ + getattr(symbol, "name", ""), + getattr(symbol, "type", ""), + getattr(symbol, "width", ""), + getattr(symbol, "offset", "") + ]) + print(table) + + # Function Table print("\nFunction Table:") + fun_table = PrettyTable() + fun_table.field_names = ["Function Name", "Return Type", "Local Var Table"] for fun in self.fun_table._table: - print(f"Function: {fun.name}, Return Type: {fun.return_type}") - if hasattr(fun, 'table'): - print(f" Local Variable Table ({fun.table.name}):") - for local_var in fun.table._table: - print(f" {vars(local_var)}") + local_table_name = getattr(fun, "table", None) + local_table_name = local_table_name.name if local_table_name else "" + fun_table.add_row([ + fun.name, + getattr(fun, "return_type", ""), + local_table_name + ]) + print(fun_table) + + # Local Variable Tables print("\nLocal Variable Tables:") - for table in self.local_var_tables: - print(f"LocalVarTable: {table.name}") - for symbol in table._table: - print(f" {vars(symbol)}") + for table_obj in self.local_var_tables: + print(f"LocalVarTable: {table_obj.name}") + local_table = PrettyTable() + local_table.field_names = ["Name", "Type", "Width", "Offset", "Is Param"] + for symbol in table_obj._table: + local_table.add_row([ + getattr(symbol, "name", ""), + getattr(symbol, "type", ""), + getattr(symbol, "width", ""), + getattr(symbol, "offset", ""), + getattr(symbol, "is_param", "") + ]) + print(local_table) class GlobalVarTable(SymbolTable): diff --git a/semantic_rule_back.py b/semantic_rule_back.py deleted file mode 100644 index b89ba46..0000000 --- a/semantic_rule_back.py +++ /dev/null @@ -1,1908 +0,0 @@ -from semantic.symbol import * -from error import SemanticError -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() - - -class SemanticRule: - """ - 语义规则 - """ - def __init__(self, node): - """ - 构造 - :param node: 树节点 - """ - self.node = node - self.errors = list() - - def __rule(self, node): - """ - 实际的语义规则,需要复写 - :param node: - """ - return [] - - def execute(self): - """ - 执行语义规则 - """ - self.__rule(self.node) - - def have_no_errors(self): - """ - 是否没有错误 - :return: 是否没有错误 - """ - return len(self.errors) == 0 - - -class SemanticRuleFactory: - """ - 语义规则工厂,根据给出的 rule_key 返回相应的实例 - """ - @classmethod - def get_instance(cls, rule_key, node): - """ - 获取语义规则实例 - :param rule_key: 关键字 - :param node: 目标节点 - :return: 实例 - """ - # 0 - if rule_key == 'Program0S': - return Program0S(node) - if rule_key == 'Program0E': - return Program0E(node) - - # 1 - if rule_key == 'DefineList0E': - return DefineList0E(node) - if rule_key == 'DefineList1E': - return DefineList1E(node) - - # 2 - if rule_key == 'Define0E': - return Define0E(node) - if rule_key == 'Define0C2': - return Define0C2(node) - - # 3 - if rule_key == 'DefineType0S': - return DefineType0S(node) - if rule_key == 'DefineType0E': - return DefineType0E(node) - if rule_key == 'DefineType0C0': - return DefineType0C0(node) - if rule_key == 'DefineType1S': - return DefineType1S(node) - if rule_key == 'DefineType1C0': - return DefineType1C0(node) - if rule_key == 'DefineType1E': - return DefineType1E(node) - - # 4 - if rule_key == 'VarDefineFollow0E': - return VarDefineFollow0E(node) - if rule_key == 'VarDefineFollow1E': - return VarDefineFollow1E(node) - - # 5 - if rule_key == 'Type0S': - return Type0S(node) - if rule_key == 'Type1S': - return Type1S(node) - - # 6 - if rule_key == 'FunDefineFollow0E': - return FunDefineFollow0E(node) - if rule_key == 'FunDefineFollow0C1': - return FunDefineFollow0C1(node) - if rule_key == 'FunDefineFollow0C3': - return FunDefineFollow0C3(node) - - # 7 - if rule_key == 'Params0S': - return Params0S(node) - if rule_key == 'Params0C0': - return Params0C0(node) - if rule_key == 'Params1S': - return Params1S(node) - - # 8 - if rule_key == 'ParamList0C0': - return ParamList0C0(node) - if rule_key == 'ParamList0C1': - return ParamList0C1(node) - - # 9 - if rule_key == 'ParamFollow0C1': - return ParamFollow0C1(node) - if rule_key == 'ParamFollow0C2': - return ParamFollow0C2(node) - - # 10 - if rule_key == 'Param0E': - return Param0E(node) - - # 11 - if rule_key == 'ArraySubscript0S': - return ArraySubscript0S(node) - if rule_key == 'ArraySubscript1S': - return ArraySubscript1S(node) - - # 12 - if rule_key == 'CodeBlock0E': - return CodeBlock0E(node) - if rule_key == 'CodeBlock0C1': - return CodeBlock0C1(node) - if rule_key == 'CodeBlock0C2': - return CodeBlock0C2(node) - - # 13 - if rule_key == 'LocalDefineList0C0': - return LocalDefineList0C0(node) - if rule_key == 'LocalDefineList0C1': - return LocalDefineList0C1(node) - - # 14 - if rule_key == 'LocalVarDefine0E': - return LocalVarDefine0E(node) - - # 15 - if rule_key == 'CodeList0E': - return CodeList0E(node) - if rule_key == 'CodeList0C0': - return CodeList0C0(node) - if rule_key == 'CodeList0C1': - return CodeList0C1(node) - if rule_key == 'CodeList1E': - return CodeList1E(node) - - # 16 - if rule_key == 'Code0E': - return Code0E(node) - if rule_key == 'Code0C0': - return Code0C0(node) - if rule_key == 'Code1E': - return Code1E(node) - if rule_key == 'Code1C0': - return Code1C0(node) - if rule_key == 'Code2E': - return Code2E(node) - if rule_key == 'Code2C0': - return Code2C0(node) - if rule_key == 'Code3E': - return Code3E(node) - if rule_key == 'Code3C0': - return Code3C0(node) - - # 17 - if rule_key == 'NormalStatement0E': - return NormalStatement0E(node) - if rule_key == 'NormalStatement1E': - return NormalStatement1E(node) - if rule_key == 'NormalStatement1C1': - return NormalStatement1C1(node) - - # 18 - if rule_key == 'NormalStatementFollow0E': - return NormalStatementFollow0E(node) - if rule_key == 'NormalStatementFollow0C0': - return NormalStatementFollow0C0(node) - if rule_key == 'NormalStatementFollow0C2': - return NormalStatementFollow0C2(node) - if rule_key == 'NormalStatementFollow1E': - return NormalStatementFollow1E(node) - if rule_key == 'NormalStatementFollow1C0': - return NormalStatementFollow1C0(node) - - # 19 - if rule_key == 'CallFollow0E': - return CallFollow0E(node) - if rule_key == 'CallFollow0C1': - return CallFollow0C1(node) - - # 20 - if rule_key == 'CallParams0E': - return CallParams0E(node) - if rule_key == 'CallParams0C0': - return CallParams0C0(node) - if rule_key == 'CallParams1E': - return CallParams1E(node) - - # 21 - if rule_key == 'CallParamList0E': - return CallParamList0E(node) - if rule_key == 'CallParamList0C0': - return CallParamList0C0(node) - if rule_key == 'CallParamList0C1': - return CallParamList0C1(node) - - # 22 - if rule_key == 'CallParamFollow0E': - return CallParamFollow0E(node) - if rule_key == 'CallParamFollow0C1': - return CallParamFollow0C1(node) - if rule_key == 'CallParamFollow0C2': - return CallParamFollow0C2(node) - if rule_key == 'CallParamFollow1E': - return CallParamFollow1E(node) - - # 23 - if rule_key == 'SelectionStatement0E': - return SelectionStatement0E(node) - if rule_key == 'SelectionStatement0C2': - return SelectionStatement0C2(node) - if rule_key == 'SelectionStatement0C5': - return SelectionStatement0C5(node) - if rule_key == 'SelectionStatement0C7': - return SelectionStatement0C7(node) - - # 24 - if rule_key == 'SelectionFollow0E': - return SelectionFollow0E(node) - if rule_key == 'SelectionFollow0C2': - return SelectionFollow0C2(node) - if rule_key == 'SelectionFollow1E': - return SelectionFollow1E(node) - - # 25 - if rule_key == 'IterationStatement0E': - return IterationStatement0E(node) - if rule_key == 'IterationStatement0C2': - return IterationStatement0C2(node) - if rule_key == 'IterationStatement0C4': - return IterationStatement0C4(node) - - # 26 - if rule_key == 'IterationFollow0E': - return IterationFollow0E(node) - if rule_key == 'IterationFollow0C1': - return IterationFollow0C1(node) - if rule_key == 'IterationFollow1E': - return IterationFollow1E(node) - if rule_key == 'IterationFollow1C0': - return IterationFollow1C0(node) - - # 27 - if rule_key == 'ReturnStatement0E': - return ReturnStatement0E(node) - if rule_key == 'ReturnStatement0C1': - return ReturnStatement0C1(node) - - # 28 - if rule_key == 'ReturnFollow0E': - return ReturnFollow0E(node) - if rule_key == 'ReturnFollow1E': - return ReturnFollow1E(node) - if rule_key == 'ReturnFollow1C0': - return ReturnFollow1C0(node) - - # 29 - if rule_key == 'VarFollow0E': - return VarFollow0E(node) - if rule_key == 'VarFollow0C1': - return VarFollow0C1(node) - if rule_key == 'VarFollow1E': - return VarFollow1E(node) - - # 30 - if rule_key == 'Expression0E': - return Expression0E(node) - if rule_key == 'Expression0C0': - return Expression0C0(node) - if rule_key == 'Expression0C1': - return Expression0C1(node) - - # 31 - if rule_key == 'ExpressionFollow0E': - return ExpressionFollow0E(node) - if rule_key == 'ExpressionFollow0C1': - return ExpressionFollow0C1(node) - if rule_key == 'ExpressionFollow1E': - return ExpressionFollow1E(node) - - # 32 - if rule_key == 'RelOp0E': - return RelOp0E(node) - if rule_key == 'RelOp1E': - return RelOp1E(node) - if rule_key == 'RelOp2E': - return RelOp2E(node) - if rule_key == 'RelOp3E': - return RelOp3E(node) - if rule_key == 'RelOp4E': - return RelOp4E(node) - if rule_key == 'RelOp5E': - return RelOp5E(node) - - # 33 - if rule_key == 'AdditiveExpr0E': - return AdditiveExpr0E(node) - if rule_key == 'AdditiveExpr0C0': - return AdditiveExpr0C0(node) - if rule_key == 'AdditiveExpr0C1': - return AdditiveExpr0C1(node) - - # 34 - if rule_key == 'AdditiveExprFollow0E': - return AdditiveExprFollow0E(node) - if rule_key == 'AdditiveExprFollow0C1': - return AdditiveExprFollow0C1(node) - if rule_key == 'AdditiveExprFollow0C2': - return AdditiveExprFollow0C2(node) - if rule_key == 'AdditiveExprFollow1E': - return AdditiveExprFollow1E(node) - - # 35 - if rule_key == 'AddOp0E': - return AddOp0E(node) - if rule_key == 'AddOp1E': - return AddOp1E(node) - - # 36 - if rule_key == 'Term0E': - return Term0E(node) - if rule_key == 'Term0C0': - return Term0C0(node) - if rule_key == 'Term0C1': - return Term0C1(node) - - # 37 - if rule_key == 'TermFollow0E': - return TermFollow0E(node) - if rule_key == 'TermFollow0C1': - return TermFollow0C1(node) - if rule_key == 'TermFollow0C2': - return TermFollow0C2(node) - - # 38 - if rule_key == 'MulOp0E': - return MulOp0E(node) - if rule_key == 'MulOp1E': - return MulOp1E(node) - if rule_key == 'MulOp2E': - return MulOp2E(node) - - # 39 - if rule_key == 'Factor0E': - return Factor0E(node) - if rule_key == 'Factor0C1': - return Factor0C1(node) - if rule_key == 'Factor1E': - return Factor1E(node) - if rule_key == 'Factor1C1': - return Factor1C1(node) - if rule_key == 'Factor2E': - return Factor2E(node) - - # 40 - if rule_key == 'IdFactorFollow0E': - return IdFactorFollow0E(node) - if rule_key == 'IdFactorFollow1E': - return IdFactorFollow1E(node) - if rule_key == 'IdFactorFollow1C1': - return IdFactorFollow1C1(node) - - # 41 - if rule_key == 'Args0E': - return Args0E(node) - if rule_key == 'Args0C0': - return Args0C0(node) - if rule_key == 'Args1E': - return Args1E(node) - - # 42 - if rule_key == 'ArgList0E': - return ArgList0E(node) - if rule_key == 'ArgList0C0': - return ArgList0C0(node) - if rule_key == 'ArgList0C1': - return ArgList0C1(node) - - # 43 - if rule_key == 'ArgListFollow0E': - return ArgListFollow0E(node) - if rule_key == 'ArgListFollow0C1': - return ArgListFollow0C1(node) - if rule_key == 'ArgListFollow0C2': - return ArgListFollow0C2(node) - if rule_key == 'ArgListFollow1E': - return ArgListFollow1E(node) - - return None - -# S 产生式开始 -# E 产生式结束 -# CN 产生式第N个元素应用之后 - - -# 0 -class Program0S(SemanticRule): - def __rule(self, node): - symbol_table_pool.init() - - def execute(self): - self.__rule(self.node) - - -class Program0E(SemanticRule): - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - - def execute(self): - self.__rule(self.node) - - -# 1 -class DefineList0E(SemanticRule): - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - for c in node.children[1].code: - node.code.append(c) - - def execute(self): - self.__rule(self.node) - - -class DefineList1E(SemanticRule): - def __rule(self, node): - node.code.clear() - - def execute(self): - self.__rule(self.node) - - -# 2 -class Define0E(SemanticRule): - def __rule(self, node): - for c in node.children[2].code: - node.code.append(c) - - def execute(self): - self.__rule(self.node) - - -class Define0C2(SemanticRule): - def __rule(self, node): - node.type = node.get_pre_brother(2).type - node.id = node.get_pre_brother(1).lexical - - def execute(self): - self.__rule(self.node) - - -# 3 -class DefineType0S(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - # 检查 type 是否是 void - if node.type == 'void': - self.errors.append(SemanticError('变量' + node.id + '不能定义为void类型')) - if node.type == 'int': - # 检查是否重定义 - if symbol_table_pool.global_var_table.exist(node.id): - self.errors.append(SemanticError('变量' + node.id + '重定义')) - - -class DefineType0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - if node.children[0].type == 'var': - symbol_table_pool.global_var_table.append( - GlobalVar(node.id, 'int', 4) - ) - if node.children[0].type == 'array': - symbol_table_pool.global_var_table.append( - GlobalVar(node.id, 'array', 4 * node.children[0].length) - ) - - -class DefineType0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.type = node.parent.type - node.id = node.parent.id - - -class DefineType1S(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - # 检查是否重定义 - if symbol_table_pool.fun_table.exist(node.id): - self.errors.append(SemanticError('函数名' + node.id + '重定义')) - - -class DefineType1C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.type = node.parent.type - node.fun = node.parent.id - - -class DefineType1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - - -# 4 -class VarDefineFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.type = 'var' - - -class VarDefineFollow1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.type = 'array' - node.length = node.children[1].lexical - - -# 5 -class Type0S(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.type = 'int' - - -class Type1S(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.type = 'void' - - -# 6 -class FunDefineFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[3].code: - node.code.append(c) - - -class FunDefineFollow0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.type = node.parent.type - node.fun = node.parent.fun - - -class FunDefineFollow0C3(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 7 -class Params0S(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - symbol_table_pool.append( - LocalVarTable(node.fun, symbol_table_pool.global_var_table) - ) - symbol_table_pool.fun_table.append( - Fun(node.fun, node.type, symbol_table_pool.query(node.fun)) - ) - - -class Params0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class Params1S(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - symbol_table_pool.append( - LocalVarTable(node.fun, symbol_table_pool.global_var_table) - ) - symbol_table_pool.fun_table.append( - Fun(node.fun, node.type, symbol_table_pool.query(node.fun)) - ) - - -# 8 -class ParamList0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class ParamList0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 9 -class ParamFollow0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class ParamFollow0C2(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 10 -class Param0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - # 先判断 type 是否为 void - if node.children[0].type == 'void': - self.errors.append(SemanticError('参数' + node.children[1].lexical + '不能定义为void类型')) - if node.children[0].type == 'int': - # 判断是否重定义 - if symbol_table_pool.query(node.fun).exist(node.children[1].lexical): - self.errors.append(SemanticError('参数' + node.children[1].lexical + '重定义')) - else: - if node.children[2].type == 'array': - symbol_table_pool.query(node.fun).append( - LocalVar(node.children[1].lexical, 'address', 4, True) - ) - if node.children[2].type == 'var': - symbol_table_pool.query(node.fun).append( - LocalVar(node.children[1].lexical, 'int', 4, True) - ) - - -# 11 -class ArraySubscript0S(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.type = 'array' - - -class ArraySubscript1S(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.type = 'var' - - -# 12 -class CodeBlock0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.code.append(node.fun + ':') - for c in node.children[2].code: - node.code.append(c) - - -class CodeBlock0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class CodeBlock0C2(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 13 -class LocalDefineList0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class LocalDefineList0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 14 -class LocalVarDefine0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - if node.children[0].type == 'void': - self.errors.append(SemanticError('变量' + node.children[1].lexical + '不能定义为void类型')) - if node.children[0].type == 'int': - if symbol_table_pool.query(node.fun).exist(node.children[1].lexical): - self.errors.append(SemanticError('变量' + node.children[1].lexical + '重定义')) - else: - if node.children[2].type == 'var': - symbol_table_pool.query(node.fun).append( - LocalVar(node.children[1].lexical, 'int', 4, False) - ) - if node.children[2].type == 'array': - symbol_table_pool.query(node.fun).append( - LocalVar(node.children[1].lexical, 'array', 4 * node.children[2].length, False) - ) - - -# 15 -class CodeList0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - for c in node.children[1].code: - node.code.append(c) - - -class CodeList0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class CodeList0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class CodeList1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.code.clear() - - -# 16 -class Code0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - - -class Code0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class Code1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - - -class Code1C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class Code2E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - - -class Code2C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class Code3E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - - -class Code3C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 17 -class NormalStatement0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.code.clear() - - -class NormalStatement1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[1].code: - node.code.append(c) - - -class NormalStatement1C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - node.id = node.get_pre_brother(1).lexical - - -# 18 -class NormalStatementFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - if node.children[0].type == 'var': - for c in node.children[2].code: - node.code.append(c) - node.code.append(node.id + ' := ' + node.children[2].name) - if node.children[0].type == 'array': - for c in node.children[0].code: - node.code.append(c) - for c in node.children[2].code: - node.code.append(c) - node.code.append(node.id + '[' + node.children[0].name + ']' + ' := ' + node.children[2].name) - - -class NormalStatementFollow0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class NormalStatementFollow0C2(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class NormalStatementFollow1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - node.code.append('call ' + node.id + ', ' + str(symbol_table_pool.query(node.id).get_params_num())) - - -class NormalStatementFollow1C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - node.id = node.parent.id - - -# 19 -class CallFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[1].code: - node.code.append(c) - - -class CallFollow0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - node.id = node.parent.id - - -# 20 -class CallParams0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - if symbol_table_pool.query(node.id).get_params_num() != node.children[0].num: - self.errors.append(SemanticError('函数体' + node.fun + '调用' + node.id + '的时候,参数数量不匹配')) - else: - for c in node.children[0].code: - node.code.append(c) - - -class CallParams0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class CallParams1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - if symbol_table_pool.query(node.fun).get_params_num() != 0: - self.errors.append(SemanticError('函数体' + node.fun + '调用' + node.id + '的时候,参数数量不匹配')) - - -# 21 -class CallParamList0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.num = 1 + node.children[1].num - for c in node.children[0].code: - node.code.append(c) - for c in node.children[1].code: - node.code.append(c) - node.code.append('param ' + node.children[0].name) - for name in node.children[1].names: - node.code.append('param ' + name) - - -class CallParamList0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class CallParamList0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 22 -class CallParamFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.num = 1 + node.children[2].num - for c in node.children[1].code: - node.code.append(c) - for c in node.children[2].code: - node.code.append(c) - node.names.append(node.children[1].name) - for n in node.children[2].names: - node.names.append(n) - - -class CallParamFollow0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class CallParamFollow0C2(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class CallParamFollow1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.num = 0 - node.code.clear() - node.names.clear() - - -# 23 -class SelectionStatement0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - if not node.children[2].bool: - self.errors.append(SemanticError('if-结构中的表达式不是bool表达式')) - else: - for c in node.children[2].code: - node.code.append(c) - if_block = get_temp_block_name() - else_block = get_temp_block_name() - next_block = get_temp_block_name() - node.code.append('if ' + node.children[2].name + ' goto ' + if_block) - - - node.code.append(if_block + ':') - for c in node.children[5].code: - node.code.append(c) - node.code.append('goto ' + next_block) - - node.code.append(else_block + ':') - - for c in node.children[7].code: - node.code.append(c) - node.code.append('goto ' + next_block) - - - node.code.append(next_block + ':') - - -class SelectionStatement0C2(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class SelectionStatement0C5(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class SelectionStatement0C7(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 24 -class SelectionFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[2].code: - node.code.append(c) - - -class SelectionFollow0C2(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class SelectionFollow1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.code.clear() - - -# 25 -class IterationStatement0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - judge_block = get_temp_block_name() - iteration_block = get_temp_block_name() - next_block = get_temp_block_name() - node.code.append(judge_block + ':') - for c in node.children[2].code: - node.code.append(c) - node.code.append('if ' + node.children[2].name + ' goto ' + iteration_block) - node.code.append('goto ' + next_block) - node.code.append(iteration_block + ':') - for c in node.children[4].code: - node.code.append(c) - node.code.append('goto ' + judge_block) - node.code.append(next_block + ':') - - -class IterationStatement0C2(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class IterationStatement0C4(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 26 -class IterationFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[1].code: - node.code.append(c) - - -class IterationFollow0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class IterationFollow1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - - -class IterationFollow1C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 27 -class ReturnStatement0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[1].code: - node.code.append(c) - - -class ReturnStatement0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 28 -class ReturnFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.code.append('return') - - -class ReturnFollow1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - node.code.append('return ' + node.children[0].name) - - -class ReturnFollow1C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 29 -class VarFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.type = 'array' - node.name = node.children[1].name - for c in node.children[1].code: - node.code.append(c) - - -class VarFollow0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class VarFollow1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.type = 'var' - - -# 30 -class Expression0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.bool = node.children[1].bool - if node.children[1].bool: - node.name = get_temp_var_name() - for c in node.children[0].code: - node.code.append(c) - for c in node.children[1].code: - node.code.append(c) - node.code.append(node.name + ' := ' + node.children[0].name + ' ' - + node.children[1].op + ' ' + node.children[1].name) - else: - node.name = node.children[0].name - for c in node.children[0].code: - node.code.append(c) - - -class Expression0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class Expression0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 31 -class ExpressionFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.bool = True - node.op = node.children[0].op - node.name = node.children[1].name - for c in node.children[1].code: - node.code.append(c) - - -class ExpressionFollow0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class ExpressionFollow1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.bool = False - - -# 32 -class RelOp0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.op = node.children[0].lexical - - -class RelOp1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.op = node.children[0].lexical - - -class RelOp2E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.op = node.children[0].lexical - - -class RelOp3E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.op = node.children[0].lexical - - -class RelOp4E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.op = node.children[0].lexical - - -class RelOp5E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.op = node.children[0].lexical - - -# 33 -class AdditiveExpr0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - if node.children[1].add: - node.name = get_temp_var_name() - for c in node.children[0].code: - node.code.append(c) - for c in node.children[1].code: - node.code.append(c) - node.code.append(node.name + ' := ' + node.children[0].name + ' ' + node.children[1].op - + ' ' + node.children[1].name) - else: - node.name = node.children[0].name - for c in node.children[0].code: - node.code.append(c) - - -class AdditiveExpr0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class AdditiveExpr0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 34 -class AdditiveExprFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.add = True - node.op = node.children[0].op - if node.children[2].add: - node.name = get_temp_var_name() - for c in node.children[1].code: - node.code.append(c) - for c in node.children[2].code: - node.code.append(c) - node.code.append(node.name + ' := ' + node.children[1].name + ' ' + node.children[2].op - + ' ' + node.children[2].name) - else: - node.name = node.children[1].name - for c in node.children[1].code: - node.code.append(c) - - -class AdditiveExprFollow0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class AdditiveExprFollow0C2(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class AdditiveExprFollow1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.add = False - - -# 35 -class AddOp0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.op = node.children[0].lexical - - -class AddOp1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.op = node.children[0].lexical - - -# 36 -class Term0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - if node.children[1].mul: - node.name = get_temp_var_name() - for c in node.children[0].code: - node.code.append(c) - for c in node.children[1].code: - node.code.append(c) - node.code.append(node.name + ' := ' + node.children[0].name + ' ' + node.children[1].op - + ' ' + node.children[1].name) - else: - node.name = node.children[0].name - for c in node.children[0].code: - node.code.append(c) - - -class Term0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class Term0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 37 -class TermFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.mul = True - node.op = node.children[0].op - if node.children[2].mul: - node.name = get_temp_var_name() - for c in node.children[1].code: - node.code.append(c) - for c in node.children[2].code: - node.code.append(c) - node.code.append(node.name + ' := ' + node.children[1].name + ' ' + node.children[2].op - + ' ' + node.children[2].name) - else: - node.name = node.children[1].name - for c in node.children[1].code: - node.code.append(c) - - -class TermFollow0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class TermFollow0C2(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 38 -class MulOp0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.op = node.children[0].lexical - - -class MulOp1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.op = node.children[0].lexical - -class MulOp2E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.op = node.children[0].lexical - - -# 39 -class Factor0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[1].code: - node.code.append(c) - node.name = node.children[1].name - - -class Factor0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class Factor1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[1].code: - node.code.append(c) - node.name = node.children[1].name - - -class Factor1C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.id = node.get_pre_brother(1).lexical - node.fun = node.parent.fun - - -class Factor2E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.name = get_temp_var_name() - node.code.append(node.name + ' := ' + node.children[0].lexical) - - -# 40 -class IdFactorFollow0E(SemanticRule): - def execute(self): - 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 - if node.children[0].type == 'array': - node.name = get_temp_var_name() - for c in node.children[0].code: - node.code.append(c) - node.code.append(node.name + ' := ' + node.id + '[' + node.children[0].name + ']') - else: - self.errors.append('变量' + node.id + '未定义') - - -class IdFactorFollow1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - if symbol_table_pool.fun_table.exist(node.id): - if node.children[1].num != symbol_table_pool.query(node.id).get_params_num(): - self.errors.append('调用函数' + node.id + '的时候参数数量不匹配') - else: - for c in node.children[1].code: - node.code.append(c) - node.code.append('call ' + node.id + ', ' + str(symbol_table_pool.query(node.fun).get_params_num())) - node.name = get_temp_var_name() - node.code.append(node.name + ' := ' + 'result') - else: - self.errors.append('函数' + node.id + '未定义') - - -class IdFactorFollow1C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 41 -class Args0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - for c in node.children[0].code: - node.code.append(c) - node.num = node.children[0].num - - -class Args0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class Args1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.code.clear() - node.num = 0 - - -# 42 -class ArgList0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.num = 1 + node.children[1].num - for c in node.children[0].code: - node.code.append(c) - for c in node.children[1].code: - node.code.append(c) - node.code.append('param ' + node.children[0].name) - for name in node.children[1].names: - node.code.append('param ' + name) - - -class ArgList0C0(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class ArgList0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -# 43 -class ArgListFollow0E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.num = 1 + node.children[2].num - for c in node.children[1].code: - node.code.append(c) - for c in node.children[2].code: - node.code.append(c) - node.names.append(node.children[1].name) - for name in node.children[2].names: - node.names.append(name) - - -class ArgListFollow0C1(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class ArgListFollow0C2(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.fun = node.parent.fun - - -class ArgListFollow1E(SemanticRule): - def execute(self): - self.__rule(self.node) - - def __rule(self, node): - node.num = 0 - node.code.clear() - node.names.clear() diff --git a/syntax/rule.py b/syntax/rule.py index 2c88e6f..bd695cf 100644 --- a/syntax/rule.py +++ b/syntax/rule.py @@ -177,6 +177,7 @@ terminal_sign_type = [ 'subtraction', 'multiplication', 'division', + 'yushu', 'bigger', 'bigger-equal', 'smaller', @@ -551,7 +552,7 @@ productions = [ ), # 49 Production('return-statement', ['return', 'return-follow'], - None, [None, None], "ReturnStatement49E", + None, [None, 'ReturnStatement49C1'], "ReturnStatement49E", ), # 50 Production('return-follow', ['semicolon'], @@ -559,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'], @@ -647,7 +648,7 @@ productions = [ None, [None, 'ArgListFollow79C1', 'ArgListFollow79C2'], 'ArgListFollow79E'), # 80 Production('arg-list-follow', [], - None, [], 'ArgListFollowE'), + None, [], 'ArgListFollow80E'), # 81 Production('arraylist-with-num', [], @@ -661,6 +662,10 @@ productions = [ # 83 Production('factor', ['float-num'], None, [None], 'Factor83E'), + + # 84 + Production('mul-op', ['yushu'], + None, [None], 'MulOp84E'), ] # 文法开始符号 diff --git a/syntax/syntax.py b/syntax/syntax.py index f5421ba..bf6525f 100644 --- a/syntax/syntax.py +++ b/syntax/syntax.py @@ -254,6 +254,7 @@ class Node: self.lexical = None self.array = None self.code = list() + self.name = None self.type = None self.id = None self.length = None 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/test7.hy b/test7.hy new file mode 100644 index 0000000..d0f76d8 --- /dev/null +++ b/test7.hy @@ -0,0 +1,29 @@ +i32 g_a; + +fn main() -> i32 { + i32 type; + i32 foo; + + i32 age; + i32 a; + + age = 32; + + if foo >= 60 { + a = 0; + + } else { + if foo >= 18 { + a = 1; + } else { + a = 2; + } + } + + while foo <= 100 { + age = age + a; + a = a + 1; + } + + return 0; +} \ No newline at end of file diff --git a/test9.c b/test9.c deleted file mode 100644 index eb42250..0000000 --- a/test9.c +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - i32 a; - a = 42; - - if a { - } - -} - diff --git a/tk_ui.py b/tk_ui.py new file mode 100644 index 0000000..cc617a8 --- /dev/null +++ b/tk_ui.py @@ -0,0 +1,67 @@ +import tkinter as tk +from tkinter import scrolledtext, messagebox +from lexical.lexical import Lexical +from syntax.syntax import Syntax + +def process_code(input_code): + lexical = Lexical() + lexical.load_source(input_code) + lexical_success = lexical.execute() + output = [] + if lexical_success: + lexical_result = lexical.get_result() + output.append('词法分析是否成功:\t' + str(lexical_success)) + output.append('\n词法分析结果:') + for i in lexical_result: + output.append(f"{i.type} {i.str} {i.line}") + output.append('') + syntax = Syntax() + syntax.put_source(lexical_result) + syntax_success = syntax.execute() + output.append('语法分析和语义分析是否成功\t' + str(syntax_success)) + if syntax_success: + output.append('\n语义分析结果:\t') + output.append('四元式代码:\t') + i = -1 + for code in syntax.get_result().root.code: + i += 1 + output.append(f"{i} \t{code}") + return '\n'.join(output), '' + else: + return '\n'.join(output), '错误原因:\t' + syntax.get_error().info + else: + return '', '错误原因:\t' + lexical.get_error().info + +def on_submit(): + input_code = input_text.get("1.0", tk.END) + output_text.delete("1.0", tk.END) + error_label.config(text="") + try: + result, error = process_code(input_code) + if result: + output_text.insert(tk.END, result) + if error: + error_label.config(text=error) + except Exception as e: + messagebox.showerror("程序异常", str(e)) + +root = tk.Tk() +root.title("C 语言编译器前端演示") + +# 输入框 +input_text = scrolledtext.ScrolledText(root, width=80, height=20) +input_text.pack(padx=10, pady=5) + +# 提交按钮 +submit_btn = tk.Button(root, text="提交", command=on_submit) +submit_btn.pack(pady=5) + +# 输出框 +output_text = scrolledtext.ScrolledText(root, width=80, height=20, bg="#000000") +output_text.pack(padx=10, pady=5) + +# 错误信息框 +error_label = tk.Label(root, text="", fg="red") +error_label.pack(pady=5) + +root.mainloop() \ No newline at end of file