1

Lua 用の ANTLR パーサーを作成しようとしています。そこで、Nicolai Mainero が作成した文法 (ANTLR のサイト、Lua 5.1 grammar で入手可能) を取り、作業を開始しました。

文法は得意です。機能しないことが 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 ...

ANTLRWikiで見つけたものに注意してください!名前が示すように、それはWikiであり、かなり簡単に投稿できます。あなたが言及しているLua文法は良いスタートですが、かなりのエラーがあります(少なくとも、私が見た時点では、2進数または16進数のリテラルも正しくありません...)。

于 2010-10-31T22:11:11.650 に答える