Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
eef872c3f8
21
LICENSE
21
LICENSE
@ -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.
|
219
README.md
219
README.md
@ -1,23 +1,208 @@
|
||||
# C(缩减版)语言编译器前端
|
||||
## 是什么
|
||||
NUAA 2017年编译原理课设,词法分析使用正则表达式,语法分析使用LL(1)文法分析器,
|
||||
语义分析使用自上而下翻译,使用 Python 语言编写,面向配置化,稍加改造可以适用其他文法
|
||||
<h1 align="center"> Hydrogen 语言大纲</h1>
|
||||
|
||||
## 怎么使用
|
||||
[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 的值)。
|
||||
|
@ -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',
|
||||
}
|
9
main.py
9
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
|
||||
|
488
rule_back.py
488
rule_back.py
@ -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')
|
187
semantic/rule.py
187
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
|
@ -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):
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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'),
|
||||
]
|
||||
|
||||
# 文法开始符号
|
||||
|
@ -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
|
||||
|
18
test.c
18
test.c
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
14
test2.c
14
test2.c
@ -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);
|
||||
}
|
16
test2.hy
Normal file
16
test2.hy
Normal file
@ -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);
|
||||
}
|
21
test3.c
21
test3.c
@ -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;
|
||||
}
|
22
test3.hy
Normal file
22
test3.hy
Normal file
@ -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;
|
||||
}
|
19
test4.c
19
test4.c
@ -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;
|
||||
}
|
20
test4.hy
Normal file
20
test4.hy
Normal file
@ -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;
|
||||
}
|
29
test5.c
29
test5.c
@ -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;
|
||||
}
|
20
test5.hy
Normal file
20
test5.hy
Normal file
@ -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);
|
||||
}
|
13
test6.c
13
test6.c
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
19
test7.c
19
test7.c
@ -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);
|
||||
}
|
29
test7.hy
Normal file
29
test7.hy
Normal file
@ -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;
|
||||
}
|
67
tk_ui.py
Normal file
67
tk_ui.py
Normal file
@ -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()
|
Loading…
Reference in New Issue
Block a user