我正在为一种脚本语言编写一个解析器,并为此使用antlr 4.5.3。
grammar VSE;
chunk
: block* EOF
;
block
: var '=' exp
| functioncall
;
var
: NAME
| var '[' exp ']'
| var '.' var
;
exp
: number
| string
| var
| functioncall
| <assoc=right> exp exp //concat
;
functioncall
: NAME '(' (exp)? (',' exp)* ')'
| var '.' functioncall
;
string
: '"' (~('"' | '\' | 'r' | 'n') | '\' ('"' | '\'))* '"'
;
NAME
: [a-zA-Z_][a-zA-Z_0-9]*
;
number
: INT | HEX | FLOAT
;
INT
: Digit+
;
HEX
: '0' [xX] [0-9a-fA-F]+
;
FLOAT
: Digit* '.' Digit+
;
Digit
: [0-9]
;
WS
: [ tu000Crn]+ -> skip
;
然而,在测试它的过程中,我发现了一个类似var = something
的变量赋值,然后在下一行中进行一些函数调用,导致了一个concat语句。(我的concat语句是一个变量,后面跟着另一个类似var = var1 var2
的变量)我理解antlr跳过所有新行以支持行延续,但我想添加一个条件,即如果两个exp
之间有一个新行,它会将它们视为两个独立的块,而不是一个concat语句。即
var = var2
functioncall(var)
这应该是两个单独的块,而不是concat语句。有办法做到这一点吗?
以下规则适合您吗?
block
: var '=' exp NEW_LINE
| functioncall NEW_LINE
;
NEW_LINE: 'r'? 'n'
WS
: [ t]+ -> skip
;
在另一种情况下,你应该使用语义谓词或非常不清楚的语法。