-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlua.llw
122 lines (116 loc) · 3.39 KB
/
lua.llw
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
// Based on https://www.lua.org/manual/5.4/manual.html#9
token BreakKw='break' ReturnKw='return' FunctionKw='function' EndKw='end' GotoKw='goto'
DoKw='do' WhileKw='while' RepeatKw='repeat' IfKw='if' ThenKw='then' UntilKw='until'
ElseifKw='elseif' ElseKw='else' ForKw='for' InKw='in' LocalKw='local' AndKw='and'
OrKw='or' NotKw='not' NilKw='nil' FalseKw='false' TrueKw='true';
token Semi=';' ColonColon='::' Colon=':' Dot='.' Comma=',' Ellipsis='...'
Equal='=' Plus='+' Minus='-' Star='*' Slash='/' SlashSlash='//' Hat='^' Percent='%'
And='&' Tilde='~' Pipe='|' GtGt='>>' LtLt='<<' DotDot='..' Less='<' LessEqual='<='
Greater='>' GreaterEqual='>=' EqualEqual='==' TildeEqual='~=' Hash='#';
token LBrak='[' RBrak=']' LParen='(' RParen=')' LBrace='{' RBrace='}';
token Name='<name>' LiteralString='<string>'
Numeral='<numeral>';
token Comment FirstLineComment Whitespace;
skip Comment FirstLineComment Whitespace;
right '..' '^';
start chunk;
chunk: chunk_block;
chunk_block: stat* [retstat] @block; // extra rule for better error handling
block: stat* [retstat];
stat^:
emptystat
| expstat
| label
| breakstat
| gotostat
| dostat
| whilestat
| repeatstat
| ifstat
| forstat
| funcstat
| localstat
;
emptystat: ';';
/// superset of official grammar, check in cst that syntax is valid
expstat: prefixexp [(',' prefixexp)* '=' explist @assignstat];
breakstat: 'break';
gotostat: 'goto' Name;
dostat: 'do' block 'end';
whilestat: 'while' exp 'do' block 'end';
repeatstat: 'repeat' block 'until' exp;
ifstat:
'if' exp 'then' block
('elseif' exp 'then' block)*
['else' block] 'end'
;
forstat:
'for' (
?1 Name '=' exp ',' exp [',' exp] 'do' block 'end' // resolve LL(1) conflict with extra lookahead
| namelist 'in' explist 'do' block 'end')
;
funcstat: 'function' funcname pars funcbody;
localstat:
'local' (
'function' Name pars funcbody @localfuncstat
| attname (',' attname)* ['=' explist]
)
;
attname: Name [attrib];
attrib: '<' Name '>';
retstat: 'return' [explist] [';'];
label: '::' Name '::';
funcname: qualname [':' Name];
qualname: Name ('.' Name)*;
namelist: Name (',' Name)*;
explist: exp (',' exp)*;
args_explist: '(' [exp (',' exp)*] ')'; // extra rule for better error handling
exp:
exp '^' exp @binexp
| ('not' | '-' | '#' | '~') exp @unaryexp
| exp ('*' | '/' | '//' | '%') exp @binexp
| exp ('+' | '-') exp @binexp
| exp '..' exp @binexp
| exp ('<<' | '>>') exp @binexp
| exp '&' exp @binexp
| exp '~' exp @binexp
| exp '|' exp @binexp
| exp ('<' | '>' | '<=' | '>=' | '~=' | '==') exp @binexp
| exp 'and' exp @binexp
| exp 'or' exp @binexp
| literalexp ^
| prefixexp ^
| tableconstructor ^
| functiondef ^
;
literalexp:
'nil'
| 'false'
| 'true'
| '...'
| Numeral
| LiteralString
;
prefixexp:
prefixexp '[' exp ']' @indexexp
| prefixexp '.' Name @fieldexp
| ?1 prefixexp (args | ':' Name args) @callexp // resolve ambiguity described in section 3.3.1
| Name @nameexp
| '(' exp ')' @parenexp
;
args^:
args_explist
| tableconstructor
| stringarg
;
stringarg: LiteralString;
functiondef: 'function' pars funcbody;
pars: '(' [Name (?1 ',' Name)* [',' '...'] | '...'] ')'; // resolve LL(1) conflict with extra lookahead
funcbody: block 'end';
tableconstructor: '{' fieldlist '}';
fieldlist: [field (?1 (',' | ';') field)* [',' | ';']]; // resolve LL(1) conflict with extra lookahead
field:
'[' exp ']' '=' exp
| ?1 Name '=' exp // resolve LL(1) conflict with extra lookahead
| exp
;