From 9034cd8abda8c2d801b68675e5ff86fb251c27b7 Mon Sep 17 00:00:00 2001 From: Gary Gan Date: Thu, 12 Jun 2025 15:14:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 324 ++++++++++++++++++++++++++++++++++++++++++++- main.py | 3 + semantic/rule.py | 1 - semantic/symbol.py | 32 +++-- syntax/rule.py | 80 ----------- tk_ui.py | 8 +- 6 files changed, 350 insertions(+), 98 deletions(-) diff --git a/README.md b/README.md index d8a47c2..875a0fb 100644 --- a/README.md +++ b/README.md @@ -205,4 +205,326 @@ fn main() { 7. **算术操作** - 执行加法运算,例如:(+, age, a, _v13)。 8. **返回操作** - - **新增**:表示函数返回特定值,例如:(return, _, _, _v18)(返回临时变量 _v18 的值)。 + - 表示函数返回特定值,例如:(return, _, _, _v18)(返回临时变量 _v18 的值)。 +9. **函数调用** + - 表示调用函数,例如:(call, product, 0, _) (product是函数名,0是参数个数)。 + +### 2.3 添加语义动作的文法推导式 + +```python +# 0 +Production('program', ['define-lists'], + 'Program0S', [None], 'Program0E'), +# 1 +Production('define-lists', ['define-list', 'define-lists'], + None, [None, None], 'DefineLists1E'), +# 2 +Production('define-lists', [], + None, [], 'DefineLists2E'), +# 3 +Production('define-list', ['fun-define'], + None, [None], 'DefineList3E', + ), +# 4 +Production('define-list', ['global-var-define'], + None, [None], 'DefineList4E', + ), +# 5 +Production('fun-define', + ['fn', 'id', 'left-parentheses', 'params', 'right-parentheses', 'fun-return', 'left-brace', 'code-block', + 'right-brace'], + None, [None, None, None, 'FunDefine5C3', None, 'FunDefine5C5', None, 'FunDefine5C7', None], 'FunDefine5E', + ), +# 6 +Production('params', [], + 'Params6S', [], None, + ), +# 7 +Production('params', ['paramlist'], + 'Params7S', ['Params7C0'], None, + ), +# 8 +Production('paramlist', ['param', 'param-follow'], + None, ['ParamList8C0', 'ParamList8C1'], None, + ), +# 9 +Production('param-follow', ['comma', 'param', 'param-follow'], + None, [None, 'ParamFollow9C1', 'ParamFollow9C2'], None, + ), +# 10 +Production('param-follow', [], + None, [], None, + ), +# 11 +Production('param', ['id', 'colon', 'type', 'arraylist'], + None, [None, None, None, None], 'Param11E', + ), +# 12 +Production('arraylist', [], + 'ArrayList12S', [], None, + ), +# 13 +Production('arraylist', ['left-bracket', 'right-bracket'], + 'ArrayList13S', [None, None], None, + ), +# 14 +Production('fun-return', [], + 'FunReturn14S', [], None, + ), +# 15 +Production('fun-return', ['right-arrow', 'type', 'arraylist'], + None, [None, None, None], 'FunReturn15E', + ), +# 16 +Production('type', ['i32'], + 'Type16S', [None], None, + ), +# 17 +Production('type', ['f32'], + 'Type17S', [None], None, + ), +# 18 +Production('type', ['void'], + "Type18S", [None], None, + ), +# 19 +Production('global-var-define', ['type', 'arraylist-with-num', 'id', 'global-var-define-follow'], + None, [None, None, None, 'GlobalVarDefine19C3'], 'GlobalVarDefine19E', + ), +# 20 +Production('global-var-define-follow', ['comma', 'id', 'global-var-define-follow'], + None, [None, None, 'GlobalVarDefineFllow20C2'], 'GlobalVarDefineFllow20E', + ), +# 21 +Production('global-var-define-follow', ['semicolon'], + None, [None], None, + ), +# 22 +Production('code-block', ['code-list'], + None, ['CodeBlock22C0'], 'CodeBlock22E', + ), +# 23 +Production('code-list', ['code', 'code-list'], + None, ["CodeList23C0", 'CodeList23C1'], 'CodeList23E', + ), +# 24 +Production('code-list', [], + None, [], 'CodeList24E', + ), +# 25 +Production('code', ['local-define'], + None, ['Code25C0'], 'Code25E', + ), +# 26 +Production('code', ['normal-statement'], + None, ['Code26C0'], 'Code26E', + ), +# 27 +Production('code', ['selection-statement'], + None, ['Code27C0'], 'Code27E', + ), +# 28 +Production('code', ['iteration-statement'], + None, ['Code28C0'], 'Code28E', + ), +# 29 +Production('code', ['return-statement'], + None, ['Code29C0'], 'Code29E', + ), +# 30 +Production('local-define', ['type', 'arraylist-with-num', 'id', 'local-define-follow'], + None, ['LocalDefine30C0', "LocalDefine30C1", 'LocalDefine30C2', 'LocalDefine30C3'], 'LocalDefine30E', + ), +# 31 +Production('local-define-follow', ['comma', 'id', 'local-define-follow'], + None, [None, 'LocalDefineFollow31C1', 'LocalDefineFollow31C2'], 'LocalDefineFollow31E', + ), +# 32 +Production('local-define-follow', ['semicolon'], + None, [None], None, + ), +# 33 +Production('normal-statement', ['semicolon'], + None, [None], None, + ), +# 34 +Production('normal-statement', ['id', 'normal-statement-follow'], + None, [None, 'NormalStatement34C1'], 'NormalStatement34E', + ), +# 35 +Production('normal-statement-follow', ['var-follow', 'evaluate', 'exp', 'semicolon'], + None, ['NormalStatementFollow35C0', None, 'NormalStatementFollow35C2', None], 'NormalStatement35E', + ), +# 36 +Production('normal-statement-follow', ['call-follow', 'semicolon'], + None, ['NormalStatementFollow36C0', None], 'NormalStatementFollow36E', + ), +# 37 +Production('var-follow', [], + None, [], 'VarFollow37E', + ), +# 38 +Production('var-follow', ['left-bracket', 'exp', 'right-bracket'], + None, [None, None, None], 'VarFollow38E', + ), +# 39 +Production('call-follow', ['left-parentheses', 'call-params', 'right-parentheses'], + None, [None, 'CallFollow39C1', None], 'CallFollow39E', + ), +# 40 +Production('call-params', ['call-param-list'], + None, ['CallParams40C0'], 'CallParams40E', + ), +# 41 +Production('call-params', [], + None, [], 'CallParams41E', + ), +# 42 +Production('call-param-list', ['exp', 'call-param-follow'], + None, ['CallParamList42C0', None], 'CallParamList42E', + ), +# 43 +Production('call-param-follow', ['comma', 'exp', 'call-param-follow'], + None, [None, 'CallParamFollow43C1', None], 'CallParamFollow43E', + ), +# 44 +Production('call-param-follow', [], + None, [], 'CallParamFollow44E', + ), + +# 45 +Production('selection-statement', ['if', 'exp', 'left-brace', 'code-list', 'right-brace', 'selection-follow'], + None, [None, 'SelectionStatement45C1', None, 'SelectionStatement45C3', None, 'SelectionStatement45C5'], 'SelectionStatement45E', + ), +# 46 +Production('selection-follow', ['else', 'left-brace', 'code-list', 'right-brace'], + None, [None, None, 'SelectionFollow46C2', None], 'SelectionFollow46E', + ), +# 47 +Production('selection-follow', [], + None, [], 'SelectionFollow47E', + ), +# 48 +Production('iteration-statement', ['while', 'exp', 'left-brace', 'code-list', 'right-brace'], + None, [None, "IterationStatement48C1", None, 'IterationStatement48C3', None], 'IterationStatement48E', + ), +# 49 +Production('return-statement', ['return', 'return-follow'], + None, [None, 'ReturnStatement49C1'], "ReturnStatement49E", + ), +# 50 +Production('return-follow', ['semicolon'], + None, [None], "ReturnFollow50E", + ), +# 51 +Production('return-follow', ['exp', 'semicolon'], + None, ['ReturnFollow51C0', None], 'ReturnFollow51E', + ), +# 52 +Production('exp', ['additive-expr', 'exp-follow'], + None, ['Exp52C0', 'Exp52C1'], 'Exp52E'), +# 53 +Production('exp-follow', ['rel-op', 'additive-expr'], + None, [None, 'ExpFollow53C1'], 'ExpFollow53E'), +# 54 +Production('exp-follow', [], + None, [], 'ExpFollow54E'), +# 55 +Production('rel-op', ['smaller-equal'], + None, [None], 'RelOp55E'), +# 56 +Production('rel-op', ['smaller'], + None, [None], 'RelOp56E'), +# 57 +Production('rel-op', ['bigger'], + None, [None], 'RelOp57E'), +# 58 +Production('rel-op', ['bigger-equal'], + None, [None], 'RelOp58E'), +# 59 +Production('rel-op', ['equal'], + None, [None], 'RelOp59E'), +# 60 +Production('rel-op', ['not-equal'], + None, [None], 'RelOp60E'), +# 61 +Production('additive-expr', ['term', 'additive-expr-follow'], + None, ['AdditiveExpr61C0', 'AdditiveExpr61C1'], 'AdditiveExpr61E'), +# 62 +Production('additive-expr-follow', ['add-op', 'term', 'additive-expr-follow'], + None, [None, 'AdditiveExprFollow62C1', 'AdditiveExprFollow62C2'], 'AdditiveExprFollow62E'), +# 63 +Production('additive-expr-follow', [], + None, [], 'AdditiveExprFollow63E'), +# 64 +Production('add-op', ['addition'], + None, [None], 'AddOp64E'), +# 65 +Production('add-op', ['subtraction'], + None, [None], 'AddOp65E'), +# 66 +Production('term', ['factor', 'term-follow'], + None, ['Term66C0', 'Term66C1'], 'Term66E'), +# 67 +Production('term-follow', ['mul-op', 'factor', 'term-follow'], + None, [None, 'TermFollow67C1', 'TermFollow67C2'], 'TermFollow67E'), +# 68 +Production('term-follow', [], + None, [], 'TermFollow68E'), +# 69 +Production('mul-op', ['multiplication'], + None, [None], 'MulOp69E'), +# 70 +Production('mul-op', ['division'], + None, [None], 'MulOp70E'), +# 71 +Production('factor', ['left-parentheses', 'exp', 'right-parentheses'], + None, [None, 'Factor71C1', None], 'Factor71E'), +# 72 +Production('factor', ['id', 'id-factor-follow'], + None, [None, 'Factor72C1'], 'Factor72E'), +# 73 +Production('factor', ['int-num'], + None, [None], 'Factor73E'), +# 74 +Production('id-factor-follow', ['var-follow'], + None, [None], 'IdFactorFollow74E'), +# 75 +Production('id-factor-follow', ['left-parentheses', 'args', 'right-parentheses'], + None, [None, 'IdFactorFollow75C1', None], 'IdFactorFollow75E'), +# 76 +Production('args', ['arg-list'], + None, ['Args76C0'], 'Args76E'), +# 77 +Production('args', [], + None, [], 'Args77E'), +# 78 +Production('arg-list', ['exp', 'arg-list-follow'], + None, ['ArgList78C0', 'ArgList78C1'], 'ArgList78E'), +# 79 +Production('arg-list-follow', ['comma', 'exp', 'arg-list-follow'], + None, [None, 'ArgListFollow79C1', 'ArgListFollow79C2'], 'ArgListFollow79E'), +# 80 +Production('arg-list-follow', [], + None, [], 'ArgListFollow80E'), + +# 81 +Production('arraylist-with-num', [], + None, [], 'ArrayListWithNum81E', + ), +# 82 +Production('arraylist-with-num', ['left-bracket', 'int-num', 'right-bracket'], + None, [None, None, None], 'ArrayListWithNum82E', + ), + +# 83 +Production('factor', ['float-num'], + None, [None], 'Factor83E'), + +# 84 +Production('mul-op', ['yushu'], + None, [None], 'MulOp84E'), +``` + + + diff --git a/main.py b/main.py index 3a6fcf6..f76ad3c 100644 --- a/main.py +++ b/main.py @@ -6,6 +6,8 @@ from syntax.syntax import Syntax from syntax.syntax import LL1Generator import sys +from semantic.rule import symbol_table_pool + # print(PredictingAnalysisTable().compile()) # obj = LL1Generator() @@ -38,6 +40,7 @@ if lexical_success: syntax_success = syntax.execute() print('语法分析和语义分析是否成功\t', syntax_success) if syntax_success: + print(symbol_table_pool.debug()) print() print('语义分析结果:\t') print('四元式代码:\t') diff --git a/semantic/rule.py b/semantic/rule.py index e973f99..c1ec777 100644 --- a/semantic/rule.py +++ b/semantic/rule.py @@ -504,7 +504,6 @@ class Program0E(SemanticRule): def __rule(self, node): for c in node.children[0].code: node.code.append(c) - symbol_table_pool.debug() def execute(self): self.__rule(self.node) diff --git a/semantic/symbol.py b/semantic/symbol.py index 2b2eb78..f3c8f0c 100644 --- a/semantic/symbol.py +++ b/semantic/symbol.py @@ -132,37 +132,39 @@ class SymbolTablePool: self.local_var_tables.append(local_var_table) def debug(self): + output = [] + # Global Variable Table - print("Global Variable Table:") + output.append("Global Variable Table:") table = PrettyTable() table.field_names = ["Name", "Type", "Width", "Offset"] for symbol in self.global_var_table._table: table.add_row([ - getattr(symbol, "name", ""), - getattr(symbol, "type", ""), - getattr(symbol, "width", ""), - getattr(symbol, "offset", "") + getattr(symbol, "name", ""), + getattr(symbol, "type", ""), + getattr(symbol, "width", ""), + getattr(symbol, "offset", "") ]) - print(table) + output.append(str(table)) # Function Table - print("\nFunction Table:") + output.append("\nFunction Table:") fun_table = PrettyTable() fun_table.field_names = ["Function Name", "Return Type", "Local Var Table"] for fun in self.fun_table._table: 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 + fun.name, + getattr(fun, "return_type", ""), + local_table_name ]) - print(fun_table) + output.append(str(fun_table)) # Local Variable Tables - print("\nLocal Variable Tables:") + output.append("\nLocal Variable Tables:") for table_obj in self.local_var_tables: - print(f"LocalVarTable: {table_obj.name}") + output.append(f"LocalVarTable: {table_obj.name}") local_table = PrettyTable() local_table.field_names = ["Name", "Type", "Width", "Offset", "Is Param"] for symbol in table_obj._table: @@ -173,7 +175,9 @@ class SymbolTablePool: getattr(symbol, "offset", ""), getattr(symbol, "is_param", "") ]) - print(local_table) + output.append(str(local_table)) + + return "\n".join(output) class GlobalVarTable(SymbolTable): diff --git a/syntax/rule.py b/syntax/rule.py index bd695cf..f0ea723 100644 --- a/syntax/rule.py +++ b/syntax/rule.py @@ -82,86 +82,6 @@ class Production: return self.str[0] -""" -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 = exp ; - | call-follow ; -20. call-follow -> ( call-params ) -21. call-params -> call-param-list - | empty -22. call-param-list -> exp call-param-follow -23. call-param-follow -> , exp call-param-follow - | empty -24. selection-statement -> if ( exp ) { code-list } selection-follow -25. selection-follow -> else { code-list } - | empty -26. iteration-statement -> while ( exp ) iteration-follow -27. iteration-follow -> { code-list } - | code -28. return-statement -> return return-follow -29. return-follow -> ; - | exp ; -30. var-follow -> [ exp ] - | empty -31. exp -> additive-expr exp-follow -32. exp-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 -> ( exp ) - | ID id-factor-follow | NUM -41. id-factor-follow -> var-follow - | ( args ) -42. args -> arg-list - | empty -43. arg-list -> exp arg-list-follow -44. arg-list-follow -> , exp arg-list-follow - | empty -""" # 所有终结符的类型 diff --git a/tk_ui.py b/tk_ui.py index cc617a8..2d7acad 100644 --- a/tk_ui.py +++ b/tk_ui.py @@ -2,6 +2,8 @@ import tkinter as tk from tkinter import scrolledtext, messagebox from lexical.lexical import Lexical from syntax.syntax import Syntax +from semantic.rule import symbol_table_pool +from syntax.syntax import LL1Generator def process_code(input_code): lexical = Lexical() @@ -20,6 +22,8 @@ def process_code(input_code): syntax_success = syntax.execute() output.append('语法分析和语义分析是否成功\t' + str(syntax_success)) if syntax_success: + output.append("\n符号表信息:\t") + output.append(symbol_table_pool.debug()) output.append('\n语义分析结果:\t') output.append('四元式代码:\t') i = -1 @@ -46,7 +50,7 @@ def on_submit(): messagebox.showerror("程序异常", str(e)) root = tk.Tk() -root.title("C 语言编译器前端演示") +root.title("Hydrogen语言编译器前端演示") # 输入框 input_text = scrolledtext.ScrolledText(root, width=80, height=20) @@ -57,7 +61,7 @@ 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 = scrolledtext.ScrolledText(root, width=80, height=20, bg="#ffffff") output_text.pack(padx=10, pady=5) # 错误信息框