2017-02-22 2 views
2

ANLTR 4:грамматики, чтобы свести на нет двух одинаковых символы в правиле лексического анализатора внутри одной строки в кавычках

мне нужно поддерживать один строку в кавычках с уцелевшими символами и способностью использовать двойные фигурные скобки в виде последовательности «бегству ', который потребует дополнительного разбора. Поэтому оба этих примера должны быть поддержаны. Меня не так беспокоит второй пример, потому что это кажется тривиальным, если я могу заставить первого работать и не совпадать с двойными фигурными фигурными фигурами.

1. 'this is a string literal with an escaped\' character' 2. 'this is a string {{functionName(x)}} literal with double curlies'

StringLiteral 
: '\'' (ESC | AnyExceptDblCurlies)*? '\'' ; 

fragment 
ESC : '\\' [btnr\'\\]; 

fragment 
AnyExceptDblCurlies 
: '{' ~'{' 
| ~'{' .; 

Я сделал много исследований по этому вопросу и понять, что вы не можете отрицать несколько персонажей, и даже видели подобный подход работы в ответе Барта на этом посту ...

Negating inside lexer- and parser rules

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

если я изменить строку правило буквальным маркера к следующему работает ...

StringLiteral 
: '\'' (ESC | .)*? '\'' ; 

Любые идеи, как обрабатывать этот сценарий лучше? Я могу вывести, что экранированный символ получает соответствие AnyExceptDblCurlies вместо ESC, но я не уверен, как решить эту проблему.

+0

действительно ли вам нужно токенизировать содержимое строкового литерала на данном этапе? вы не говорите, какой у вас вариант использования грамматики; я думаю о языках, таких как C или C#, которые обычно оставляют разбор литералов для функций времени выполнения, printf, String.Format и т. п. – dlatikay

+0

@dlatikay, мне нужно проанализировать случай, когда в литере есть «{{x} } ', поэтому я не могу отложить до времени выполнения. Вы полагаете, что может быть проще справиться с этим случаем на уровне правила парсера? – ichrisnichols

+0

Я вижу ... да, правила парсера> это напоминает мне [этот] (http://stackoverflow.com/questions/1850468/parsing-string-interpolation-in-antlr) – dlatikay

ответ

1

Для анализа определения шаблона из строки в значительной степени требуется обработка в синтаксическом анализаторе. Используйте режимы lexer для различения строковых символов и имени шаблона.

Parser:

options { 
    tokenVocab = TesterLexer ; 
} 

test : string EOF ; 
string : STRBEG (SCHAR | template)* STREND ; // allow multiple templates per string 
template : TMPLBEG TMPLNAME TMPLEND ; 

Лексер:

STRBEG : Squote -> pushMode(strMode) ; 

mode strMode ; 
    STRESQ : Esqote -> type(SCHAR) ; // predeclare SCHAR in tokens block 
    STREND : Squote -> popMode ; 
    TMPLBEG : DBrOpen -> pushMode(tmplMode) ; 
    STRCHAR : .  -> type(SCHAR) ; 

mode tmplMode ; 
    TMPLEND : DBrClose -> popMode ; 
    TMPLNAME : ~'}'* ; 

fragment Squote : '\'' ; 
fragment Esqote : '\\\'' ; 
fragment DBrOpen : '{{' ; 
fragment DBrClose : '}}' ; 

Обновлено исправить правила TMPLNAME, добавьте основное правило и опции блокировки.

+0

это выглядит точно, что мне нужно ... Я продолжаю ударять по кирпичной стене, пытаясь использовать семантические предикаты, но использование стека режимов выглядит как билет! Позвольте мне попробовать это ... не могу поверить, что этот сценарий требует такого уровня артикуляции. – ichrisnichols

+0

GRosenberg, я не могу получить даже самые простые версии вашего примера для компиляции в ANTLR с таргетингом на C# (.NET 4.5.2) ... Я исправил несколько ошибок в вашем примере, но даже по-прежнему не могу показаться совпадающим даже простая строка с одиночными кавычками ... Я покажу свой код в обновлении основного потока. Пожалуйста, дайте мне знать, если я что-то упустил. – ichrisnichols

+0

Появляется, что в синтаксическом анализаторе отсутствует блок опций: 'options { \t tokenVocab = TesterLexer; } 'Это стандартное требование для всех разбитых грамматик. – GRosenberg

Смежные вопросы