ANTLR Lua长字符串语法规则

时间:2010-10-31 21:51:14

标签: parsing lua antlr lexer antlr3

我正在尝试为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: '[[' (~(']') | ']'(~(']')))* ']]';

有人能帮助我吗?谢谢!

1 个答案:

答案 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语法是一个很好的开始,但它有很多错误(二进制或十六进制文字也不正确,至少,在我查看它的时候......)。