Как пропустить неразборчивый текст с помощью antlr4?

Я пытался создать парсер с antlr4 для небольшой системы шаблонов, которая мне нужна. Шаблон так же, как вы можете видеть некоторые функции, которые всегда начинаются с равного количества '{{' и '}}', и внутри него определена функция, которая будет пропущена и выполнена и должна заменить все это результатом этой функции. .

Проблема в том, что я хочу оставить весь остальной текст вне функций и просто анализировать то, что я определяю. Прямо сейчас STRING не соответствует другому тексту или оставляет его в покое. Я хочу пропустить или игнорировать весь полный текст, кроме определенных функций.

В конечном итоге цель состоит в том, чтобы заменить всю часть {{..}} результатом функции.

Есть ли способ пропустить весь остальной текст?

Вот образец текста:

allkinds of text $#@ {{getMetaSelf option1}} blabla bla {{getEnv test test}} now repeat something: {{repeatPerInstance test ','}} 
this will get repeated. sub functions are possible here now: {{getMetaInstance option1}} blabla {{endrepeat}} more text.

Это то, что мне удалось до сих пор:

parse: EOF | (functions | STRING)* ;

functions : '{{' func STRING*
          ;

func : getterFunctions
     | 'repeatPerInstance ' KEYWORD ( ' ' delimiter )? '}}' ( '{{' ( getterFunctions | repeatSubFunctions ) )*  '{{endrepeat}}'
     ;

getterFunctions : 'getEnv ' KEYWORD ' ' KEYWORD '}}'
                | 'getMetaSelf ' metaoptions '}}'
                ;

repeatSubFunctions : 'getEnvRole' KEYWORD '}}'
                   | 'getMetaInstance' metaoptions '}}'
                   ;


metaoptions : 'option1'
            | 'option2'
            | 'option3'
            | 'option4'
            ;

delimiter : '\'' ',' '\'' ;

STRING : . +? ;

KEYWORD : [0-9A-Za-z\-\_]+ ;
WS  : [ \t\n\r]+ -> skip ;

person wernerb    schedule 08.04.2014    source источник


Ответы (2)


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

lexer grammar MyLexer;

TEXT
  : ( ~'{'
    | '{' {_input.LA(1) != '{'}?
    )+
  ;

OPEN_TAG
  : '{{' -> pushMode(InTag)
  ;

mode InTag;

  END_TAG
    : '}}' -> popMode
    ;

  // other rules for tokens inside of {{ ... }} go here
person Sam Harwell    schedule 09.04.2014
comment
Спасибо! Я просто не знаю, как это проверить/реализовать. Когда я компилирую это с помощью antlr4, я получаю classnotfound для синтаксического анализатора грамматики. Как проверить это, проанализировав файл или текст? - person wernerb; 09.04.2014

Кстати.:

Следующая строка кажется странной, так как она принимает STRINGs после функции, которая, вероятно, не была предназначена:

функции: '{{' func STRING* ;

Я бы также смоделировал функции таким образом (не проверено), что группирует {{ }}:

parse: (function | STRING)* EOF ;


function : '{{' 
            functionBody
            '}}'
          ;

functionBody 
     : getterFunctions
     | 'repeatPerInstance ' KEYWORD ( ' ' delimiter )? '}}' ( '{{' ( getterFunctions | repeatSubFunctions ) '}}')*  '{{endrepeat'
     ;

getterFunctions : 'getEnv ' KEYWORD ' ' KEYWORD 
                | 'getMetaSelf ' metaoptions 
                ;

repeatSubFunctions : 'getEnvRole' KEYWORD 
                   | 'getMetaInstance' metaoptions 
                   ;
person Onur    schedule 09.04.2014