我正在匹配用户定义的HTML模板标记,它们看起来像这样(简化):
{% label %} ... {% endlabel %}
"标签"是用户可以自己定义的字母数字值,例如:
{% mytag %}<div>...</div>{% endmytag %}
有没有办法告诉解析器LABEL
开始标记文本必须与ENDLABEL
结束标记文本匹配?换句话说,我希望这是无效的:
{% mytag %}<div>...</div>{% endnotmatchingtag %}
我的lexer是这样的:
LABEL : ALPHA (ALPHA|DIGIT|UNDERSCORE)* ;
fragment UNDERSCORE: '_' ;
fragment ALPHA: [a-zA-Z] ;
fragment DIGIT: [0-9] ;
END : 'end'
ENDLABEL : END LABEL
TAGSTART : '{%'
TAGEND : '%}'
WS : [ trn]+ -> skip ;
解析器规则看起来类似于此:
customtag: TAGSTART LABEL TAGEND block TAGSTART ENDLABEL TAGEND;
(并且块递归地匹配文本或其他标签)
现在我正在侦听器中检查匹配,但我希望我能在解析器中完成。是否有任何方法可以确保ENDLABEL
在Antlr4中的解析器级别等于'end'
+LABEL
?
如果我没有在lexer中预写"end",有可能做到吗?
创建两个额外的lexer规则
EndTag : TAGSTART ENDLABEL TAGEND;
StartTag : TAGSTART LABEL TAGEND;
请确保标记ENDLABEL未包含在LABEL中(但LABEL与相同的文本匹配,但由于它在语法中是第一个,因此是首选!)
在语法中使用新的标记,与您所做的类似:
taggedElement : StartTag othernodes EndTag;
并插入语义谓词
taggedElement : StartTag othernodes EndTag {matches($StartTag.text,$EndTag.text)};
其中如果标签匹配,则CCD_ 6为真。
在你的schenario中,我会创建一个访问者来强制执行你的语义。ANTLR 4可以为您生成抽象访问者和基础访问者,然后您可以对其进行扩展。