java
  • antlr
  • 2009-10-08 2 views 3 likes 
    3

    У меня есть несколько правил Antlr, что я не знаю, как заставить их работатьANTLR неоднозначная грамматика?

    Первое правило:

    STRING_LITERAL 
        : '"' (EscapeSequence | ~('\\'|'"'))* '"' 
        ; 
    

    Второе правило:

    element 
    : name '=' math_formula ; 
    math_formula 
         :  '"' expression '"'; 
    

    Выражение регулярное C-подобное выражение

    Пример синтаксиса

    "count" = "array[3]" 
    

    счетчик должен быть строкой, в то время как массив [3] должен быть выражением

    Моя проблема заключается в том, что лексический всегда возвращается как «счетчик» и «массив [3]», как струны, и синтаксический анализатор не может распознать выражение.

    Я использую цель java.

    EDIT: изменено "variable_name" на "count".

    EDIT2: объяснил свою вторую попытку ниже:

    я могу обнаружить начало выражения с «=«», но я не буду в состоянии обнаружить конец выражения в Lexer, в результате чего ложное обнаружение строк, когда у меня есть 2 элемента, разделенные «»

    "count1" = "array[1]", 
    "count2" = "array[2]" 
    

    , если я использовал «=«», как START_EXPRESSION, лексер обнаружил цитата окончания первого выражения, и цитату, начиная вторую строку в виде string ", \ n", что явно неверно.

    EDIT 3: Попытка синтаксических предикатов

    Я изменил правила для STRING_LITERAL к

    STRING_LITERAL 
        : (~('=') '"' (EscapeSequence | ~('\\'|'"'))* '"')=> '"' (EscapeSequence | ~('\\'|'"'))* '"' 
        ; 
    

    Еще не работает, и я не знаю, как производить ~ (» = ') в самом правиле, присваивая ему метку элемента или somthing

    ответ

    1

    Я не могу вспомнить синтаксис сейчас, потому что прошло более 10 лет, но одна из ключевых сильных сторон ANTLR - это произвольный просмотр с обратным отсчетом. Итак, всякий раз, когда вы видите двойную кавычку, посмотрите, соответствуют ли совпадения element. Если это так, используйте поток как element; если нет, вернитесь к правилу STRING_LITERAL.


    Я вернул обратно в справочник ANTLR и нашел пример синтаксического предиката. Адаптация, что, я думаю, что ваше правило будет выглядеть примерно так:

    protected 
    STRING : whatever... 
    ; 
    protected 
    EXPRESSION: whatever... 
    ; 
    STRING_OR_EXPR 
    : (EXPRESSION) => EXPRESSION { $setType(EXPRESSION); } 
    | STRING { $setType(STRING); } 
    ; 
    
    +0

    Проблема заключается в том, что выражение является правилом Parser, тогда как STRING является правилом lexer. Что вы описали выше, предполагает, что EXPRESSION является правилом lexer, и это не так. Или я могу понять что-то не так (новичок в ANTLR) – 2009-10-08 17:16:06

    +0

    Нет, вы правы; Я забыл об этом. Я думаю, что что-то подобное можно сделать на уровне анализатора. Я посмотрю еще немного, когда у меня будет время. – erickson

    +0

    protected был преобразован в фрагмент в ANTLR v3. –

    0

    Трудно сказать, что анализатор эффективно принимает, учитывая то, как он отображается на этом SO веб-страницы, и, возможно, данные цитаты, добавленные для emphaisis.Так простите это baisc предположение, но если ANTLR эффективно получает

    "variable_name" = "array[3]" 
    

    (обратите внимание на кавычки), это будет звучать как два STRING_LITERAL лексем, разделенных знаком равенства, для которых он, вероятно, не имеет никакого правила.

    variable_name = "array[3]" 
    

    или, может быть, лучше

    variable_name = array[3] 
    

    является то, что вы пытаетесь сделать.

    РЕДАКТИРОВАТЬ:
    После выяснения, что имя является СТРОКИ (определенное в другом месте, никаких кавычек), то ее ясно, что вышеуказанные догадки «начинают не» быть правильными. Тем не менее, еще одна проблема в том, что, если выражение не определен с символами запрещенных в STRING_LITTERAL, math_formula будет неоднозначным с ним, и, следовательно, лексер не увидит элемент, но последовательность «имя» = «STRING_LITERAL», для которой у нее нет правил.

    +0

    Нет, кавычки являются правильной частью синтаксиса языка – 2009-10-08 17:13:26

    +0

    и моя проблема, как вы описали, ANTLR lexer возвращает два STRING_LITERAL из-за котировок – 2009-10-08 17:18:37

    +0

    @unknown Я вижу, что math_formula делает, но как насчет имени? Каково правило для имени? Включает ли он также кавычки и отличается ли содержание в кавычках от того, что было бы правильным выражением – mjv

    0

    Какой язык для болтовни вы пытаетесь разобрать? Рискну предположить, что ваш лучший выбор, чтобы добавить состояние к вашему лексере вдоль этих линий:

    ASSIGN: 
        ('=' '"')=> /* assuming whitespace doesn't exist */ 
        '=' {some_global_flaggy_thing=1;} 
        |'=' 
        ; 
    STRING_LITERAL: 
        {some_global_flaggy_thing==1}? '"' {$type=QUOTE; some_gobal_flaggy_thing=2;} 
        |{some_global_flaggy_thing==2}? '"' {$type=QUOTE; some_global_flaggy_thing=0;} 
        | '"' /* normal string literal stuff */ '"' 
        ; 
    

    Конечно, ваша встраиваемая выражение не может иметь строковые литералы в нем.
    Примечание: Я больше знаком с ANTLR2

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