-
Notifications
You must be signed in to change notification settings - Fork 1
/
bluefin.g4
107 lines (71 loc) · 2.65 KB
/
bluefin.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
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
grammar bluefin;
program : (funcDef | varDecl | structDef)+ ;
funcDef : Virtual? type ID '(' paramList? ')' Override? '{' stmt* '}' ;
type : builtinType
| ID ;
builtinType : TInt | TFloat | TString | TBool | TVoid ;
paramList : param (',' param)* ;
param : type ID;
block : '{' stmt* '}' ;
stmt : stmtIf
| stmtWhile
| stmtReturn
| stmtBreak
| stmtContinue
| block
| stmtExpr
| varDecl ;
stmtIf : 'if' '(' expr ')' block ('else' block)? ;
stmtWhile : 'while' '(' expr ')' block ;
stmtReturn : 'return' expr? ';' ;
stmtBreak : 'break' ';' ;
stmtContinue : 'continue' ';' ;
stmtExpr : expr ';' ;
structDef : 'struct' ID (superClass)? '{' (varDecl | funcDef)* '}' ';' ;
// A varDecl in a struct is known as a 'field'
// A funcDef in a struct is known as a 'method'
superClass : 'extends' ID;
varDecl : type ID ('=' expr)? ';' ;
/* ANTLR is left-associative by default and resolves ambiguity by selecting top-most alternative
It also resolves direct left recrusion so don't need to manually remove them
This means that precedence and associativeness ambiguities are solved
TODO: handle power (right associative)
*/
expr : INT # primaryInt
| FLOAT # primaryFloat
| STRING # primaryString
| ID # primaryId
| BOOL # primaryBool
| '(' expr ')' # primaryParenth
| ID '(' argList? ')' # funcCall
| expr '.' ID '(' argList? ')' # methodCall
| expr '.' ID # memberAccess
| op=('-' | '!') expr # unaryExpr
| expr op=('*' | '/') expr # multiExpr
| expr op=('+' | '-') expr # addExpr
| expr op=('<' | '<=' | '>' | '>=') expr # relExpr
| expr op=('==' | '!=') expr # equalityExpr
| expr ('&&') expr # logicalANDExpr
| expr ('||') expr # logicalORExpr
|<assoc=right> expr '=' expr # simpleAssignExpr
;
argList : expr (',' expr)* ;
TInt : 'int' ;
TFloat : 'float' ;
TString : 'string' ;
TBool : 'bool' ;
TVoid : 'void' ;
FLOAT: DIGIT+ '.' DIGIT+ ;
BOOL: 'true' | 'false' ;
STRING : '"' .*? '"' ; // no escaping " for now
Override: 'override' ;
Virtual: 'virtual' ;
ID : LETTER+; // only characters
INT : DIGIT+; // even '007' and '000' are ints
WS : [ \t\r\n]+ -> skip;
LINE_COMMENT : '//' .*? '\n' -> skip;
MULTILINE_COMMENT : '/*' .*? '*/' -> skip;
fragment
LETTER : [a-zA-Z];
fragment
DIGIT : [0-9];