0%

编译原理-杂记

阅读更多

1 CFG文法Demo

一些成熟语言的CFG文法定义,有助于我们理解、自定义一些CFG文法

1.1 Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
Java Syntax Specification
Programs
<compilation unit> ::= <package declaration>? <import declarations>? <type declarations>?
Declarations
<package declaration> ::= package <package name> ;
<import declarations> ::= <import declaration> | <import declarations> <import declaration>

<import declaration> ::= <single type import declaration> | <type import on demand declaration>

<single type import declaration> ::= import <type name> ;

<type import on demand declaration> ::= import <package name> . * ;

<type declarations> ::= <type declaration> | <type declarations> <type declaration>

<type declaration> ::= <class declaration> | <interface declaration> | ;

<class declaration> ::= <class modifiers>? class <identifier> <super>? <interfaces>? <class body>

<class modifiers> ::= <class modifier> | <class modifiers> <class modifier>

<class modifier> ::= public | abstract | final

<super> ::= extends <class type>

<interfaces> ::= implements <interface type list>

<interface type list> ::= <interface type> | <interface type list> , <interface type>

<class body> ::= { <class body declarations>? }

<class body declarations> ::= <class body declaration> | <class body declarations> <class body declaration>

<class body declaration> ::= <class member declaration> | <static initializer> | <constructor declaration>

<class member declaration> ::= <field declaration> | <method declaration>

<static initializer> ::= static <block>

<constructor declaration> ::= <constructor modifiers>? <constructor declarator> <throws>? <constructor body>

<constructor modifiers> ::= <constructor modifier> | <constructor modifiers> <constructor modifier>

<constructor modifier> ::= public | protected | private

<constructor declarator> ::= <simple type name> ( <formal parameter list>? )

<formal parameter list> ::= <formal parameter> | <formal parameter list> , <formal parameter>

<formal parameter> ::= <type> <variable declarator id>

<throws> ::= throws <class type list>

<class type list> ::= <class type> | <class type list> , <class type>

<constructor body> ::= { <explicit constructor invocation>? <block statements>? }

<explicit constructor invocation>::= this ( <argument list>? ) | super ( <argument list>? )

<field declaration> ::= <field modifiers>? <type> <variable declarators> ;

<field modifiers> ::= <field modifier> | <field modifiers> <field modifier>

<field modifier> ::= public | protected | private | static | final | transient | volatile

<variable declarators> ::= <variable declarator> | <variable declarators> , <variable declarator>

<variable declarator> ::= <variable declarator id> | <variable declarator id> = <variable initializer>

<variable declarator id> ::= <identifier> | <variable declarator id> [ ]

<variable initializer> ::= <expression> | <array initializer>

<method declaration> ::= <method header> <method body>

<method header> ::= <method modifiers>? <result type> <method declarator> <throws>?

<result type> ::= <type> | void

<method modifiers> ::= <method modifier> | <method modifiers> <method modifier>

<method modifier> ::= public | protected | private | static | abstract | final | synchronized | native

<method declarator> ::= <identifier> ( <formal parameter list>? )

<method body> ::= <block> | ;

<interface declaration> ::= <interface modifiers>? interface <identifier> <extends interfaces>? <interface body>

<interface modifiers> ::= <interface modifier> | <interface modifiers> <interface modifier>

<interface modifier> ::= public | abstract

<extends interfaces> ::= extends <interface type> | <extends interfaces> , <interface type>

<interface body> ::= { <interface member declarations>? }

<interface member declarations> ::= <interface member declaration> | <interface member declarations> <interface member declaration>

<interface member declaration> ::= <constant declaration> | <abstract method declaration>

<constant declaration> ::= <constant modifiers> <type> <variable declarator>

<constant modifiers> ::= public | static | final

<abstract method declaration>::= <abstract method modifiers>? <result type> <method declarator> <throws>? ;

<abstract method modifiers> ::= <abstract method modifier> | <abstract method modifiers> <abstract method modifier>

<abstract method modifier> ::= public | abstract

<array initializer> ::= { <variable initializers>? , ? }

<variable initializers> ::= <variable initializer> | <variable initializers> , <variable initializer>

<variable initializer> ::= <expression> | <array initializer>

Types
<type> ::= <primitive type> | <reference type>
<primitive type> ::= <numeric type> | boolean

<numeric type> ::= <integral type> | <floating-point type>

<integral type> ::= byte | short | int | long | char

<floating-point type> ::= float | double

<reference type> ::= <class or interface type> | <array type>

<class or interface type> ::= <class type> | <interface type>

<class type> ::= <type name>

<interface type> ::= <type name>

<array type> ::= <type> [ ]

Blocks and Commands
<block> ::= { <block statements>? }
<block statements> ::= <block statement> | <block statements> <block statement>

<block statement> ::= <local variable declaration statement> | <statement>

<local variable declaration statement> ::= <local variable declaration> ;

<local variable declaration> ::= <type> <variable declarators>

<statement> ::= <statement without trailing substatement> | <labeled statement> | <if then statement> | <if then else statement> | <while statement> | <for statement>

<statement no short if> ::= <statement without trailing substatement> | <labeled statement no short if> | <if then else statement no short if> | <while statement no short if> | <for statement no short if>

<statement without trailing substatement> ::= <block> | <empty statement> | <expression statement> | <switch statement> | <do statement> | <break statement> | <continue statement> | <return statement> | <synchronized statement> | <throws statements> | <try statement>

<empty statement> ::= ;

<labeled statement> ::= <identifier> : <statement>

<labeled statement no short if> ::= <identifier> : <statement no short if>

<expression statement> ::= <statement expression> ;

<statement expression> ::= <assignment> | <preincrement expression> | <postincrement expression> | <predecrement expression> | <postdecrement expression> | <method invocation> | <class instance creation expression>

<if then statement>::= if ( <expression> ) <statement>

<if then else statement>::= if ( <expression> ) <statement no short if> else <statement>

<if then else statement no short if> ::= if ( <expression> ) <statement no short if> else <statement no short if>

<switch statement> ::= switch ( <expression> ) <switch block>

<switch block> ::= { <switch block statement groups>? <switch labels>? }

<switch block statement groups> ::= <switch block statement group> | <switch block statement groups> <switch block statement group>

<switch block statement group> ::= <switch labels> <block statements>

<switch labels> ::= <switch label> | <switch labels> <switch label>

<switch label> ::= case <constant expression> : | default :

<while statement> ::= while ( <expression> ) <statement>

<while statement no short if> ::= while ( <expression> ) <statement no short if>

<do statement> ::= do <statement> while ( <expression> ) ;

<for statement> ::= for ( <for init>? ; <expression>? ; <for update>? ) <statement>

<for statement no short if> ::= for ( <for init>? ; <expression>? ; <for update>? ) <statement no short if>

<for init> ::= <statement expression list> | <local variable declaration>

<for update> ::= <statement expression list>

<statement expression list> ::= <statement expression> | <statement expression list> , <statement expression>

<break statement> ::= break <identifier>? ;

<continue statement> ::= continue <identifier>? ;

<return statement> ::= return <expression>? ;

<throws statement> ::= throw <expression> ;

<synchronized statement> ::= synchronized ( <expression> ) <block>

<try statement> ::= try <block> <catches> | try <block> <catches>? <finally>

<catches> ::= <catch clause> | <catches> <catch clause>

<catch clause> ::= catch ( <formal parameter> ) <block>

<finally > ::= finally <block>

Expressions
<constant expression> ::= <expression>
<expression> ::= <assignment expression>

<assignment expression> ::= <conditional expression> | <assignment>

<assignment> ::= <left hand side> <assignment operator> <assignment expression>

<left hand side> ::= <expression name> | <field access> | <array access>

<assignment operator> ::= = | *= | /= | %= | += | -= | <<= | >>= | >>>= | &= | ^= | |=

<conditional expression> ::= <conditional or expression> | <conditional or expression> ? <expression> : <conditional expression>

<conditional or expression> ::= <conditional and expression> | <conditional or expression> || <conditional and expression>

<conditional and expression> ::= <inclusive or expression> | <conditional and expression> && <inclusive or expression>

<inclusive or expression> ::= <exclusive or expression> | <inclusive or expression> | <exclusive or expression>

<exclusive or expression> ::= <and expression> | <exclusive or expression> ^ <and expression>

<and expression> ::= <equality expression> | <and expression> & <equality expression>

<equality expression> ::= <relational expression> | <equality expression> == <relational expression> | <equality expression> != <relational expression>

<relational expression> ::= <shift expression> | <relational expression> < <shift expression> | <relational expression> > <shift expression> | <relational expression> <= <shift expression> | <relational expression> >= <shift expression> | <relational expression> instanceof <reference type>

<shift expression> ::= <additive expression> | <shift expression> << <additive expression> | <shift expression> >> <additive expression> | <shift expression> >>> <additive expression>

<additive expression> ::= <multiplicative expression> | <additive expression> + <multiplicative expression> | <additive expression> - <multiplicative expression>

<multiplicative expression> ::= <unary expression> | <multiplicative expression> * <unary expression> | <multiplicative expression> / <unary expression> | <multiplicative expression> % <unary expression>

<cast expression> ::= ( <primitive type> ) <unary expression> | ( <reference type> ) <unary expression not plus minus>

<unary expression> ::= <preincrement expression> | <predecrement expression> | + <unary expression> | - <unary expression> | <unary expression not plus minus>

<predecrement expression> ::= -- <unary expression>

<preincrement expression> ::= ++ <unary expression>

<unary expression not plus minus> ::= <postfix expression> | ~ <unary expression> | ! <unary expression> | <cast expression>

<postdecrement expression> ::= <postfix expression> --

<postincrement expression> ::= <postfix expression> ++

<postfix expression> ::= <primary> | <expression name> | <postincrement expression> | <postdecrement expression>

<method invocation> ::= <method name> ( <argument list>? ) | <primary> . <identifier> ( <argument list>? ) | super . <identifier> ( <argument list>? )

<field access> ::= <primary> . <identifier> | super . <identifier>

<primary> ::= <primary no new array> | <array creation expression>

<primary no new array> ::= <literal> | this | ( <expression> ) | <class instance creation expression> | <field access> | <method invocation> | <array access>

<class instance creation expression> ::= new <class type> ( <argument list>? )

<argument list> ::= <expression> | <argument list> , <expression>

<array creation expression> ::= new <primitive type> <dim exprs> <dims>? | new <class or interface type> <dim exprs> <dims>?

<dim exprs> ::= <dim expr> | <dim exprs> <dim expr>

<dim expr> ::= [ <expression> ]

<dims> ::= [ ] | <dims> [ ]

<array access> ::= <expression name> [ <expression> ] | <primary no new array> [ <expression>]

Tokens
<package name> ::= <identifier> | <package name> . <identifier>
<type name> ::= <identifier> | <package name> . <identifier>

<simple type name> ::= <identifier>

<expression name> ::= <identifier> | <ambiguous name> . <identifier>

<method name> ::= <identifier> | <ambiguous name>. <identifier>

<ambiguous name>::= <identifier> | <ambiguous name>. <identifier>

<literal> ::= <integer literal> | <floating-point literal> | <boolean literal> | <character literal> | <string literal> | <null literal>

<integer literal> ::= <decimal integer literal> | <hex integer literal> | <octal integer literal>

<decimal integer literal> ::= <decimal numeral> <integer type suffix>?

<hex integer literal> ::= <hex numeral> <integer type suffix>?

<octal integer literal> ::= <octal numeral> <integer type suffix>?

<integer type suffix> ::= l | L

<decimal numeral> ::= 0 | <non zero digit> <digits>?

<digits> ::= <digit> | <digits> <digit>

<digit> ::= 0 | <non zero digit>

<non zero digit> ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

<hex numeral> ::= 0 x <hex digit> | 0 X <hex digit> | <hex numeral> <hex digit>

<hex digit> :: = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | A | B | C | D | E | F

<octal numeral> ::= 0 <octal digit> | <octal numeral> <octal digit>

<octal digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7

<floating-point literal> ::= <digits> . <digits>? <exponent part>? <float type suffix>?

<digits> <exponent part>? <float type suffix>?

<exponent part> ::= <exponent indicator> <signed integer>

<exponent indicator> ::= e | E

<signed integer> ::= <sign>? <digits>

<sign> ::= + | -

<float type suffix> ::= f | F | d | D

<boolean literal> ::= true | false

<character literal> ::= ' <single character> ' | ' <escape sequence> '

<single character> ::= <input character> except ' and \

<string literal> ::= " <string characters>?"

<string characters> ::= <string character> | <string characters> <string character>

<string character> ::= <input character> except " and \ | <escape character>

<null literal> ::= null

<keyword> ::= abstract | boolean | break | byte | case | catch | char | class | const | continue | default | do | double | else | extends | final | finally | float | for | goto | if | implements | import | instanceof | int | interface | long | native | new | package | private | protected | public | return | short | static | super | switch | synchronized | this | throw | throws | transient | try | void | volatile | while

The character set for Java is Unicode, a 16-bit character set. This is the set denoted by <input character>. Unicode effectively contains the familiar 7-bit ASCII characters as a subset, and includes "escape code" designations of the form \udddd (where each d is from <hex digit>). In the extended BNF for Java the optional appearance of X is written X?, and the iterative appearance of X is written {X}.
The syntax category <identifier> consists of strings that must start with a letter - including underscore (_) and dollar sign ($) - followed by any number of letters and digits. Characters of numerous international languages are recognized as "letters" in Java. A Java letter is a character for which the method Character.isJavaLetter returns true. A Java letter-or-digit is a character for which the method Character.isJaveLetterOrDigit returns true. Also, <identifier> includes none of the keywords given above - these are reserved words in Java.

The only BNF extention used here is the optional construct which is written with '?' added as a suffix to a terminal or non-terminal. Note that '*', '{', and '}' are all terminal symbols. This BNF definition does not address such pragmatic issues as comment conventions and the use of "white space" to delimit tokens. This BNF also does not express numerous "context-sensitive" restrictions on syntax. For instance, type use of identifiers must be consistent with the required declarations, there are size limitations on numerical literals, etc.

1.2 Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# Grammar for Python

# NOTE WELL: You should also follow all the steps listed at
# https://devguide.python.org/grammar/

# Start symbols for the grammar:
# single_input is a single interactive statement;
# file_input is a module or sequence of commands read from an input file;
# eval_input is the input for the eval() functions.
# NB: compound_stmt in single_input is followed by extra NEWLINE!
single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
file_input: (NEWLINE | stmt)* ENDMARKER
eval_input: testlist NEWLINE* ENDMARKER

decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
decorators: decorator+
decorated: decorators (classdef | funcdef | async_funcdef)

async_funcdef: ASYNC funcdef
funcdef: 'def' NAME parameters ['->' test] ':' suite

parameters: '(' [typedargslist] ')'
typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [',' [
'*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]]
| '**' tfpdef [',']]]
| '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]]
| '**' tfpdef [','])
tfpdef: NAME [':' test]
varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [
'*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]]
| '**' vfpdef [',']]]
| '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]]
| '**' vfpdef [',']
)
vfpdef: NAME

stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) |
('=' (yield_expr|testlist_star_expr))*)
annassign: ':' test ['=' test]
testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
'<<=' | '>>=' | '**=' | '//=')
# For normal and annotated assignments, additional restrictions enforced by the interpreter
del_stmt: 'del' exprlist
pass_stmt: 'pass'
flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
break_stmt: 'break'
continue_stmt: 'continue'
return_stmt: 'return' [testlist]
yield_stmt: yield_expr
raise_stmt: 'raise' [test ['from' test]]
import_stmt: import_name | import_from
import_name: 'import' dotted_as_names
# note below: the ('.' | '...') is necessary because '...' is tokenized as ELLIPSIS
import_from: ('from' (('.' | '...')* dotted_name | ('.' | '...')+)
'import' ('*' | '(' import_as_names ')' | import_as_names))
import_as_name: NAME ['as' NAME]
dotted_as_name: dotted_name ['as' NAME]
import_as_names: import_as_name (',' import_as_name)* [',']
dotted_as_names: dotted_as_name (',' dotted_as_name)*
dotted_name: NAME ('.' NAME)*
global_stmt: 'global' NAME (',' NAME)*
nonlocal_stmt: 'nonlocal' NAME (',' NAME)*
assert_stmt: 'assert' test [',' test]

compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt
async_stmt: ASYNC (funcdef | with_stmt | for_stmt)
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
while_stmt: 'while' test ':' suite ['else' ':' suite]
for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
try_stmt: ('try' ':' suite
((except_clause ':' suite)+
['else' ':' suite]
['finally' ':' suite] |
'finally' ':' suite))
with_stmt: 'with' with_item (',' with_item)* ':' suite
with_item: test ['as' expr]
# NB compile.c makes sure that the default except clause is last
except_clause: 'except' [test ['as' NAME]]
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT

test: or_test ['if' or_test 'else' test] | lambdef
test_nocond: or_test | lambdef_nocond
lambdef: 'lambda' [varargslist] ':' test
lambdef_nocond: 'lambda' [varargslist] ':' test_nocond
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*
# <> isn't actually a valid comparison operator in Python. It's here for the
# sake of a **future** import described in PEP 401 (which really works :-)
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
star_expr: '*' expr
expr: xor_expr ('|' xor_expr)*
xor_expr: and_expr ('^' and_expr)*
and_expr: shift_expr ('&' shift_expr)*
shift_expr: arith_expr (('<<'|'>>') arith_expr)*
arith_expr: term (('+'|'-') term)*
term: factor (('*'|'@'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power
power: atom_expr ['**' factor]
atom_expr: [AWAIT] atom trailer*
atom: ('(' [yield_expr|testlist_comp] ')' |
'[' [testlist_comp] ']' |
'{' [dictorsetmaker] '}' |
NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')
testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] )
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
subscriptlist: subscript (',' subscript)* [',']
subscript: test | [test] ':' [test] [sliceop]
sliceop: ':' [test]
exprlist: (expr|star_expr) (',' (expr|star_expr))* [',']
testlist: test (',' test)* [',']
dictorsetmaker: ( ((test ':' test | '**' expr)
(comp_for | (',' (test ':' test | '**' expr))* [','])) |
((test | star_expr)
(comp_for | (',' (test | star_expr))* [','])) )

classdef: 'class' NAME ['(' [arglist] ')'] ':' suite

arglist: argument (',' argument)* [',']

# The reason that keywords are test nodes instead of NAME is that using NAME
# results in an ambiguity. ast.c makes sure it's a NAME.
# "test '=' test" is really "keyword '=' test", but we have no such token.
# These need to be in a single rule to avoid grammar that is ambiguous
# to our LL(1) parser. Even though 'test' includes '*expr' in star_expr,
# we explicitly match '*' here, too, to give it proper precedence.
# Illegal combinations and orderings are blocked in ast.c:
# multiple (test comp_for) arguments are blocked; keyword unpackings
# that precede iterable unpackings are blocked; etc.
argument: ( test [comp_for] |
test '=' test |
'**' test |
'*' test )

comp_iter: comp_for | comp_if
comp_for: [ASYNC] 'for' exprlist 'in' or_test [comp_iter]
comp_if: 'if' test_nocond [comp_iter]

# not used in grammar, but may appear in "node" passed from Parser to Compiler
encoding_decl: NAME

yield_expr: 'yield' [yield_arg]
yield_arg: 'from' test | testlist

1.3 Mysql

MySQLParser.g4

1.4 Jack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
program -> classlist
classlist -> classlist class
| class
class -> class ID { classVarDecList subroutineDecList }
classVarDecList -> classVarDecList classVarDec
|
classVarDec -> static type varNameList ;
| field type varNameList ;
varNameList -> varNameList , ID
| ID
type -> int
| float
| char
| boolean
| void
| ID
subroutineDecList -> subroutineDecList subroutineDec
|
subroutineDec -> constructor type ID ( params ) subroutineBody
| function type ID ( params ) subroutineBody
| method type ID (params ) subroutineBody
params -> paramList
|
paramList -> paramList , param
| param
param -> type ID
subroutineBody -> { varDecList statements }
varDecList -> varDecList varDec
|
varDec -> type varNameList ;
statements -> statements statement
|
statement -> assign_statement
| if_statement
| while_statement
| return_statement
| call_statement ;
assign_statement -> leftValue = expression ;
leftValue -> ID
| ID [ expression ]
if_statement -> if ( expression ) statement
| if ( expression ) statement else statement
while_statement -> while ( expression ) { statement }
return_statement -> return ;
| return expression ;
call_statement -> ID ( expressions )
| ID . ID ( expressions )
expressions -> expression_list
|
expression_list -> expression_list , expression
| expression
expression -> expression & boolExpression
| expression | boolExpression
| boolExpression
boolExpression -> additive_expression relational_operator additive_expression
| additive_expression
relational_operator -> <=
| >=
| ==
| <
| >
| !=
additive_expression -> additive_expression + term
| additive_expression – term
| term
term -> term * factor
| term / factor
| factor
factor -> - positive_factor
| positive_factor
positive_factor -> ~ not_factor
| not_factor
not_factor -> INT_CONST
| CHAR_CONST
| STRING_CONST
| keywordConstant
| ID
| ID [ expression ]
| call_expression
| ( expression )
keywordConstant -> true
| false
| null
| this
call_expression -> ID ( expression )
| ID . ID ( expression )

2 CFG文法定义

2.1 运算表达式

要求

  1. 支持函数调用
  2. 支持&&以及||
  3. 支持<=>=<>等算数运算符
  4. 支持()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
expression -> expression || bool_expression 
| bool_expression

bool_expression -> bool_expression && comparable_expression
| comparable_expression

comparable_expression -> comparable_expression comparable_operator range_expression
| range_expression

range_expression -> range_expression range_operator [ expression_list ]
| factory

factory -> ( expression )

factory -> call_expression

call_expression -> id ( expressions )

expressions -> expression_list
| ε

expression_list -> expression_list , expression
| expression

factory -> number
| string
| property_expression

comparable_operator -> <
| <=
| >
| >=
| !=
| ==

range_operator -> between
| in

3 参考