ANTLR Lua правила длинной строковой грамматики - PullRequest
1 голос
/ 01 ноября 2010

Я пытаюсь создать парсер ANTLR для Lua. Поэтому я взял грамматику Николая Майнеро (доступна на сайте ANTLR, грамматика Lua 5.1) и начал работать.

Грамматика это хорошо. Одна вещь не работает: LONG STRINGS.

Правило спецификации Lua: Literal

строки также могут быть определены с помощью длинный формат, заключенный в длинные скобки. Мы определяем открывающую длинную скобку уровень 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: '[[' (~(']') | ']'(~(']')))* ']]';

Может кто-нибудь мне помочь? Спасибо!

1 Ответ

1 голос
/ 01 ноября 2010

Однажды я написал грамматику 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! Как следует из названия: это Вики, и можно довольно легко публиковать материалы. Упомянутая вами грамматика Lua - хорошее начало, но в ней есть немало ошибок (двоичные или шестнадцатеричные литералы также неверны, по крайней мере, в тот момент, когда я на это смотрел ...).

...