我正在尝试为Lua创建ANTLR解析器。所以我采用Nicolai Mainero制作的语法(可在ANTLR的网站上获得,Lua 5.1语法)并开始工作。
语法很好。有一点不起作用:LONG STRINGS。
Lua规范规则:Literal
也可以使用a定义字符串 长括号括起来的长格式。 我们定义了一个开头长支架 等级n作为开口方括号 然后是n个等号,然后是 另一个开口方括号。所以,一个 打开0级的长括号是 写作[[,开头长括号 级别1写为[= [,等等 上。定义了一个结束长括号 类似的;例如,结束 4级长括号写成 ] ====]。一个长字符串以a开头 打开任何级别的长支架 在第一个关闭长支架结束 相同的水平。文字在这 括号内可以运行几个 线条,不解释任何逃脱 序列,并忽略长括号 任何其他级别。他们可以包含 除了结束括号之外的任何东西 适当的水平。适当的水平。
我的问题与this的含义相近,但工具不同。
LONGSTRING的一些小例子:
local a = [==[ Some interesting string [=[ sub string in string ]=] [hello indexes] [[And some line strings]] ]==] - its correct string.
local f = [==[ Not interesting string ]=] - incorrect string
这里我的LONGSTRING规则没有'='符号:
LONGSTRING: '[[' (~(']') | ']'(~(']')))* ']]';
有人能帮助我吗?谢谢!
答案 0 :(得分:1)
我曾根据规范编写了一个Lua语法并解决了这个问题:
grammar Lua;
// ... options ...
// ... tokens ...
@lexer::members {
public boolean noCloseAhead(int numEqSigns) {
if(input.LA(1) != ']') return true;
for(int i = 2; i < numEqSigns+2; i++) {
if(input.LA(i) != '=') return true;
}
return input.LA(numEqSigns+2) != ']';
}
public void matchClose(int numEqSigns) throws MismatchedTokenException {
StringBuilder eqSigns = new StringBuilder();
for(int i = 0; i < numEqSigns; i++) {
eqSigns.append('=');
}
match("]"+eqSigns+"]");
}
}
// ... parser rules ...
String
: '"' (~('"' | '\\') | EscapeSequence)* '"'
| '\'' (~('\'' | '\\') | EscapeSequence)* '\''
| LongBracket
;
Comment
: (BlockComment | LineComment) {skip();}
;
fragment
BlockComment
: '--' LongBracket
;
fragment
LineComment
: '--' ~('\r' | '\n')* ('\r'? '\n' | EOF)
;
fragment
LongBracket
@init {int openEq = 0;}
: '[' ('=' {openEq++;})* '[' ({noCloseAhead(openEq)}?=> .)* {matchClose(openEq);}
;
// ... more lexer rules ...
小心你在ANTLR Wiki上发现的内容!顾名思义:它是一个Wiki,人们可以相当容易地发布内容。你提到的Lua语法是一个很好的开始,但它有很多错误(二进制或十六进制文字也不正确,至少,在我查看它的时候......)。