Проблема разбора ANTLR - PullRequest
       14

Проблема разбора ANTLR

0 голосов
/ 16 декабря 2009

Мне нужно иметь возможность сопоставить определенную строку ('[' then any number of equals signs or none then '['), затем мне нужно сопоставить подходящую закрывающую скобку (']' then the same number of equals signs then ']') после некоторых других правил сопоставления. ((options{greedy=false;}:.)*, если вы должны знать). Я понятия не имею, как это сделать в ANTLR, как я могу это сделать?

Пример: мне нужно соответствовать [===[whatever arbitrary text ]===], но не [===[whatever arbitrary text ]==].

Мне нужно сделать это и для произвольного числа знаков равенства, , поэтому в этом и заключается проблема: как мне заставить его совпадать с равным количеством знаков равенства на открытом, как на закрытии? Представленные правила синтаксического анализа до сих пор, похоже, не имеют смысла, поскольку помогают.

Ответы [ 2 ]

2 голосов
/ 16 декабря 2009

Вы не можете легко написать лексер для него, вам нужны правила синтаксического анализа. Два правила должно быть достаточно. Один отвечает за сопоставление фигурных скобок, другой - за сопоставление знаков равенства.

Примерно так:

braces : '[' ']'
       | '[' equals ']'
       ;

equals : '=' equals '='
       | '=' braces '='
       ;

Это должно охватывать описанный вами вариант использования. Не абсолютный страх, но, возможно, вам придется использовать предикат в первом правиле «равных», чтобы избежать двусмысленных интерпретаций.

Edit:

Трудно интегрировать ваше жадное правило и в то же время избежать переключения контекста лексера или чего-то подобного (сложно в ANTLR). Но если вы хотите немного интегрировать Java в свой грамматик, вы можете написать правило лексера.

В следующем примере грамматики показано, как:

grammar TestLexer;

SPECIAL :   '[' { int counter = 0; } ('=' { counter++; } )+ '[' (options{greedy=false;}:.)* ']' ('=' { counter--; } )+ { if(counter != 0) throw new RecognitionException(input); } ']';

ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;

WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;

rule    :   ID
    |   SPECIAL
    ;
0 голосов
/ 16 декабря 2009

Ваши теги упоминают лексинг, но сам ваш вопрос - нет. То, что вы пытаетесь сделать, является нерегулярным, поэтому я не думаю, что это можно сделать как часть лексинга (хотя я не помню, является ли лексер ANTLR строго регулярным - это было пару лет назад использовал ANTLR).

Однако то, что вы описываете, должно быть возможным при разборе. Вот грамматика того, что вы описали:

thingy : LBRACKET middle RBRACKET;
middle : EQUAL middle EQUAL
       | LBRACKET RBRACKET;
...