-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathminipy3.g4
68 lines (63 loc) · 2.08 KB
/
minipy3.g4
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
grammar minipy3;
// 解析器规则(Parser Rules)
program: (statement NEWLINE | NEWLINE)* EOF;
statement: simpleStmt | compoundStmt;
simpleStmt: assignmentStmt | returnStmt;
compoundStmt: ifStmt | whileStmt | forStmt | funcDef;
assignmentStmt: IDENTIFIER ASSIGN expression | arrayMember ASSIGN expression;
returnStmt: RETURN expression?;
ifStmt: IF condition COLON NEWLINE program (elifStmt | elseStmt)?;
elifStmt: ELIF condition COLON NEWLINE program (elifStmt | elseStmt)?;
elseStmt: ELSE COLON NEWLINE program;
whileStmt: WHILE condition COLON NEWLINE program;
forStmt: FOR IDENTIFIER IN expression COLON NEWLINE program;
funcDef: DEF IDENTIFIER LPAREN parameters? RPAREN COLON NEWLINE program;
parameters: IDENTIFIER (COMMA IDENTIFIER)*;
condition: logicExpr;
logicExpr: comparison (logicOp comparison)*;
comparison: NOT comparison | algebraicExpr (conditionOp algebraicExpr)?;
logicOp: AND | OR;
expression: algebraicExpr | STRING_LITERAL | list | TRUE | FALSE;
algebraicExpr: term termTail;
termTail: (PLUS term termTail) | (MINUS term termTail) | ;
term: factor factorTail;
factorTail: (MULTIPLY factor factorTail) | (DIVIDE factor factorTail) | ;
factor: IDENTIFIER | NUMBER | LPAREN algebraicExpr RPAREN | funcCall | arrayMember;
funcCall: IDENTIFIER LPAREN (expression (COMMA expression)*)? RPAREN;
list: LBRACKET (expression (COMMA expression)*)? RBRACKET;
arrayMember: IDENTIFIER LBRACKET expression RBRACKET;
// 词法规则(Lexer Rules)
RETURN: 'return';
IF: 'if';
ELIF: 'elif';
ELSE: 'else';
WHILE: 'while';
FOR: 'for';
IN: 'in';
DEF: 'def';
AND: 'and';
OR: 'or';
NOT: 'not';
ASSIGN: '=';
COLON: ':';
COMMA: ',';
PLUS: '+';
MINUS: '-';
MULTIPLY: '*';
DIVIDE: '//';
LPAREN: '(';
RPAREN: ')';
LBRACKET: '[';
RBRACKET: ']';
TRUE: 'True';
FALSE: 'False';
NEWLINE: '\r'? '\n' INDENT?;
INDENT: ('\t')+;
WS: [ \t]+ -> skip;
conditionOp: '==' | '!=' | '>' | '<' | '>=' | '<=';
IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*;
NUMBER: '-'? [0-9]+ ('.' [0-9]+)?;
STRING_LITERAL:
('"' (~["\r\n] | '""')* '"')
|
('\'' (~['\r\n] | '\'\'')* '\'');