655 lines
20 KiB
Python
655 lines
20 KiB
Python
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 = 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
|
|
"""
|
|
|
|
|
|
# 所有终结符的类型
|
|
terminal_sign_type = [
|
|
'fn',
|
|
'else',
|
|
'if',
|
|
'int',
|
|
'return',
|
|
'void',
|
|
'while',
|
|
'addition',
|
|
'subtraction',
|
|
'multiplication',
|
|
'division',
|
|
'bigger',
|
|
'bigger-equal',
|
|
'smaller',
|
|
'smaller-equal',
|
|
'equal',
|
|
'not-equal',
|
|
'evaluate',
|
|
'semicolon',
|
|
'comma',
|
|
'left-parentheses',
|
|
'right-parentheses',
|
|
'left-bracket',
|
|
'right-bracket',
|
|
'left-brace',
|
|
'right-brace',
|
|
'float-num',
|
|
'int-num',
|
|
'id',
|
|
'colon',
|
|
'right-arrow',
|
|
'i32',
|
|
'f32',
|
|
# 在这之前添加非终结符类型,请务必不要动 'pound'
|
|
'pound'
|
|
]
|
|
|
|
# 所有非终结符的类型
|
|
non_terminal_sign_type = [
|
|
'program',
|
|
'define-lists',
|
|
'define-list',
|
|
'define',
|
|
'define-type',
|
|
'var-define-follow',
|
|
'type',
|
|
'fun-define',
|
|
'fun-define-follow',
|
|
'params',
|
|
'param-list',
|
|
'param-follow',
|
|
'param',
|
|
'arraylist',
|
|
'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',
|
|
'selection-follow',
|
|
'iteration-statement',
|
|
'iteration-follow',
|
|
'return-statement',
|
|
'return-follow',
|
|
# 'eval-statement',
|
|
# 'var',
|
|
'var-follow',
|
|
'exp',
|
|
'exp-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',
|
|
'global-var-define',
|
|
'fun-return',
|
|
'paramlist',
|
|
'arraylist',
|
|
'global-var-define-follow',
|
|
'local-define',
|
|
'local-define-follow',
|
|
'arraylist-with-num'
|
|
|
|
]
|
|
|
|
"""
|
|
0. program -> define-lists
|
|
1. define-lists -> define-list define-lists
|
|
2. define-lists ->
|
|
3. define-list -> fun-define
|
|
4. define-list -> global-var-define
|
|
5. fun-define -> fn id left-parentheses params right-parentheses fun-return left-brace code-block right-brace
|
|
6. params ->
|
|
7. params -> paramlist
|
|
8. paramlist -> param param-follow
|
|
9. param-follow -> comma param-follow
|
|
10. param-follow ->
|
|
11. param -> id colon type arraylist
|
|
12. arraylist ->
|
|
13. arraylist -> left-bracket right-bracket
|
|
14. fun-return ->
|
|
15. fun-return -> right-arrow type arraylist
|
|
16. type -> i32
|
|
17. type -> f32
|
|
18. type -> void
|
|
19. global-var-define -> type arraylist id global-var-define-follow
|
|
20. global-var-define-follow -> comma id global-var-define-follow
|
|
21. global-var-define-follow -> semicolon
|
|
22. code-block -> code-list
|
|
23. code-list -> code code-list
|
|
24. code-list ->
|
|
25. code -> local-define
|
|
26. code -> normal-statement
|
|
27. code -> selection-statement
|
|
28. code -> iteration-statement
|
|
29. code -> return-statement
|
|
30. local-define -> type arraylist id local-define-follow
|
|
31. local-define-follow -> comma id local-define-follow
|
|
32. local-define-follow -> semicolon
|
|
33. normal-statement -> semicolon
|
|
34. normal-statement -> id normal-statement-follow
|
|
35. normal-statement-follow -> var-follow equal exp semicolon
|
|
36. normal-statement-follow -> call-follow semicolon
|
|
37. var-follow ->
|
|
38. var-follow -> left-bracket exp right-bracket
|
|
39. call-follow -> left-parentheses call-params right-parentheses
|
|
40. call-params -> call-param-list
|
|
41. call-params ->
|
|
42. call-param-list -> exp call-param-follow
|
|
43. call-param-follow -> comma exp call-param-follow
|
|
44. call-param-follow ->
|
|
45. selection-statement -> if exp left-brace code-list right-brace selection-follow
|
|
46. selection-follow -> else left-brace code-list right-brace
|
|
47. selection-follow ->
|
|
48. iteration-statement -> while exp left-brace code-list right-brace
|
|
49. return-statement -> return return-follow
|
|
50. return-follow -> semicolon
|
|
51. return-follow -> exp semicolon
|
|
52. exp -> additive-expr exp-follow
|
|
53. exp-follow -> rel-op additive-expr
|
|
54. exp-follow ->
|
|
55. rel-op -> smaller-equal
|
|
56. rel-op -> smaller
|
|
57. rel-op -> bigger
|
|
58. rel-op -> bigger-equal
|
|
59. rel-op -> equal
|
|
60. rel-op -> not-equal
|
|
61. additive-expr -> term additive-expr-follow
|
|
62. additive-expr-follow -> add-op term additive-expr-follow
|
|
63. additive-expr-follow ->
|
|
64. add-op -> addition
|
|
65. add-op -> subtraction
|
|
66. term -> factor term-follow
|
|
67. term-follow -> mul-op factor term-follow
|
|
68. term-follow ->
|
|
69. mul-op -> multiplication
|
|
70. mul-op -> division
|
|
71. factor -> left-parentheses exp right-parentheses
|
|
72. factor -> id id-factor-follow
|
|
73. factor -> num
|
|
74. id-factor-follow -> var-follow
|
|
75. id-factor-follow -> left-parentheses args right-parentheses
|
|
76. args -> arg-list
|
|
77. args ->
|
|
78. arg-list -> exp arg-list-follow
|
|
79. arg-list-follow -> comma exp arg-list-follow
|
|
80. arg-list-follow ->
|
|
|
|
|
|
"""
|
|
|
|
|
|
# 文法产生式
|
|
productions = [
|
|
# 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, None, 'FunDefine5C7'], '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'], 'Code26E',
|
|
),
|
|
# 28
|
|
Production('code', ['iteration-statement'],
|
|
None, ['Code28C0'], 'Code25E',
|
|
),
|
|
# 29
|
|
Production('code', ['return-statement'],
|
|
None, ['Code29C0'], 'Code25E',
|
|
),
|
|
# # 30
|
|
# Production('local-define', ['type', 'arraylist', 'id', 'local-define-follow'],
|
|
# None, [None, None, None, None], None,
|
|
# ),
|
|
# # 31
|
|
# Production('local-define-follow', ['comma', 'id', 'local-define-follow'],
|
|
# None, [None, None, None], None,
|
|
# ),
|
|
# # 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, None], None,
|
|
# ),
|
|
# # 35
|
|
# Production('normal-statement-follow', ['var-follow', 'equal', 'exp', 'semicolon'],
|
|
# None, [None, None, None, None], None,
|
|
# ),
|
|
# # 36
|
|
# Production('normal-statement-follow', ['call-follow', 'semicolon'],
|
|
# None, [None], None,
|
|
# ),
|
|
# # 37
|
|
# Production('var-follow', [],
|
|
# None, [], None,
|
|
# ),
|
|
# # 38
|
|
# Production('var-follow', ['left-bracket', 'exp', 'right-bracket'],
|
|
# None, [None, None, None], None,
|
|
# ),
|
|
# # 39
|
|
# Production('call-follow', ['left-parentheses', 'call-params', 'right-parentheses'],
|
|
# None, [None, None, None], None,
|
|
# ),
|
|
# # 40
|
|
# Production('call-params', ['call-param-list'],
|
|
# None, [None], None,
|
|
# ),
|
|
# # 41
|
|
# Production('call-params', [],
|
|
# None, [], None,
|
|
# ),
|
|
# # 42
|
|
# Production('call-param-list', ['exp', 'call-param-follow'],
|
|
# None, [None, None], None,
|
|
# ),
|
|
# # 43
|
|
# Production('call-param-follow', ['comma', 'exp', 'call-param-follow'],
|
|
# None, [None, None, None], None,
|
|
# ),
|
|
# # 44
|
|
# Production('call-param-follow', [],
|
|
# None, [], None,
|
|
# ),
|
|
# # 45
|
|
# Production('selection-statement', ['if', 'exp', 'left-brace', 'code-list', 'right-brace', 'selection-follow'],
|
|
# None, [None, None, None, None, None, None], None,
|
|
# ),
|
|
# # 46
|
|
# Production('selection-follow', ['else', 'left-brace', 'code-list', 'right-brace'],
|
|
# None, [None, None, None, None], None,
|
|
# ),
|
|
# # 47
|
|
# Production('selection-follow', [],
|
|
# None, [], None,
|
|
# ),
|
|
# # 48
|
|
# Production('iteration-statement', ['while', 'exp', 'left-brace', 'code-list', 'right-brace'],
|
|
# None, [None, None, None, None, None], None,
|
|
# ),
|
|
# # 49
|
|
# Production('return-statement', ['return', 'return-follow'],
|
|
# None, [None, None], None,
|
|
# ),
|
|
# # 50
|
|
# Production('return-follow', ['semicolon'],
|
|
# None, [None], None,
|
|
# ),
|
|
# # 51
|
|
# Production('return-follow', ['exp', 'semicolon'],
|
|
# None, [None, None], None,
|
|
# ),
|
|
# # 52
|
|
# Production('exp', ['additive-expr', 'exp-follow'],
|
|
# None, ['exp0C0', 'exp0C1'], 'exp0E'),
|
|
# # 53
|
|
# Production('exp-follow', ['rel-op', 'additive-expr'],
|
|
# None, [None, 'expFollow0C1'], 'expFollow0E'),
|
|
# # 54
|
|
# Production('exp-follow', [],
|
|
# None, [], 'expFollow1E'),
|
|
# # 55
|
|
# Production('rel-op', ['smaller-equal'],
|
|
# None, [None], 'RelOp0E'),
|
|
# # 56
|
|
# Production('rel-op', ['smaller'],
|
|
# None, [None], 'RelOp1E'),
|
|
# # 57
|
|
# Production('rel-op', ['bigger'],
|
|
# None, [None], 'RelOp2E'),
|
|
# # 58
|
|
# Production('rel-op', ['bigger-equal'],
|
|
# None, [None], 'RelOp3E'),
|
|
# # 59
|
|
# Production('rel-op', ['equal'],
|
|
# None, [None], 'RelOp4E'),
|
|
# # 60
|
|
# Production('rel-op', ['not-equal'],
|
|
# None, [None], 'RelOp5E'),
|
|
# # 61
|
|
# Production('additive-expr', ['term', 'additive-expr-follow'],
|
|
# None, ['AdditiveExpr0C0', 'AdditiveExpr0C1'], 'AdditiveExpr0E'),
|
|
# # 62
|
|
# Production('additive-expr-follow', ['add-op', 'term', 'additive-expr-follow'],
|
|
# None, [None, 'AdditiveExprFollow0C1', 'AdditiveExprFollow0C2'], 'AdditiveExprFollow0E'),
|
|
# # 63
|
|
# Production('additive-expr-follow', [],
|
|
# None, [], 'AdditiveExprFollow1E'),
|
|
# # 64
|
|
# Production('add-op', ['addition'],
|
|
# None, [None], 'AddOp0E'),
|
|
# # 65
|
|
# Production('add-op', ['subtraction'],
|
|
# None, [None], 'AddOp1E'),
|
|
# # 66
|
|
# Production('term', ['factor', 'term-follow'],
|
|
# None, ['Term0C0', 'Term0C1'], 'Term0E'),
|
|
# # 67
|
|
# Production('term-follow', ['mul-op', 'factor', 'term-follow'],
|
|
# None, [None, 'TermFollow0C1', 'TermFollow0C2'], 'TermFollow0E'),
|
|
# # 68
|
|
# Production('term-follow', [],
|
|
# None, [], None),
|
|
# # 69
|
|
# Production('mul-op', ['multiplication'],
|
|
# None, [None], 'MulOp0E'),
|
|
# # 70
|
|
# Production('mul-op', ['division'],
|
|
# None, [None], 'MulOp1E'),
|
|
# # 71
|
|
# Production('factor', ['left-parentheses', 'exp', 'right-parentheses'],
|
|
# None, [None, 'Factor0C1', None], 'Factor0E'),
|
|
# # 72
|
|
# Production('factor', ['id', 'id-factor-follow'],
|
|
# None, [None, 'Factor1C1'], 'Factor1E'),
|
|
# # 73
|
|
# Production('factor', ['num'],
|
|
# None, [None], 'Factor2E'),
|
|
# # 74
|
|
# Production('id-factor-follow', ['var-follow'],
|
|
# None, [None], 'IdFactorFollow0E'),
|
|
# # 75
|
|
# Production('id-factor-follow', ['left-parentheses', 'args', 'right-parentheses'],
|
|
# None, [None, 'IdFactorFollow1C1', None], 'IdFactorFollow1E'),
|
|
# # 76
|
|
# Production('args', ['arg-list'],
|
|
# None, ['Args0C0'], 'Args0E'),
|
|
# # 77
|
|
# Production('args', [],
|
|
# None, [], 'Args1E'),
|
|
# # 78
|
|
# Production('arg-list', ['exp', 'arg-list-follow'],
|
|
# None, ['ArgList0C0', 'ArgList0C1'], 'ArgList0E'),
|
|
# # 79
|
|
# Production('arg-list-follow', ['comma', 'exp', 'arg-list-follow'],
|
|
# None, [None, 'ArgListFollow0C1', 'ArgListFollow0C2'], 'ArgListFollow0E'),
|
|
# # 80
|
|
# Production('arg-list-follow', [],
|
|
# None, [], 'ArgListFollow1E'),
|
|
|
|
# 81
|
|
Production('arraylist-with-num', [],
|
|
None, [], 'ArrayListWithNum81E',
|
|
),
|
|
# 82
|
|
Production('arraylist-with-num', ['left-bracket', 'int-num', 'right-bracket'],
|
|
None, [None, None, None], 'ArrayListWithNum82E',
|
|
)
|
|
]
|
|
|
|
# 文法开始符号
|
|
grammar_start = Sign('program') |