1

我正在尝试为 Lua 创建 ANTLR 解析器。所以我采用了 Nicolai Mainero 制作的语法(可在 ANTLR 的网站上获得,Lua 5.1 语法)并开始工作。

语法很好。一件事不起作用:长字符串。

Lua 规范规则:字面量

字符串也可以使用长括号括起来的长格式来定义。我们将第 n 级的左长括号定义为一个左方括号,后跟 n 个等号,然后是另一个左方括号。因此,级别 0 的左长括号写为 [[,级别 1 的左长括号写为 [=[,依此类推。闭合长括号的定义类似;例如,第 4 级的右长括号写为]====]。长字符串以任何级别的左长括号开始,并在同一级别的第一个右长括号结束。这种括号形式的文字可以运行多行,不解释任何转义序列,并忽略任何其他级别的长括号。它们可以包含除了适当级别的右括号之外的任何内容。适当的级别。

我的问题与接近,但工具不同。

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: '[[' (~(']') | ']'(~(']')))* ']]';

有人可以帮助我吗?谢谢!

4

1 回答 1

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

于 2010-10-31T22:11:11.650 回答