我一直在尝试使用 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
;