如何使用 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  : [ tnr]+ -> skip ;

为此,您可以使用多模式词法分析器。由于文件以自由格式文本开头,因此默认模式将是包含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

顺便说一句:

以下行看起来很奇怪,因为它在函数之后接受STRING s,这可能不是有意的:

函数 : '{{' 函数字符串* ;

我也会以这种方式对函数进行建模(未测试),它将{{ }}分组:

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 
                   ;

相关内容

  • 没有找到相关文章

最新更新