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