antlr4 解析器能否看到匹配的开始和结束文本模式?
Can the antlr4 parser see matching opening and closing text pattern?
我正在匹配用户定义的 HTML-模板标签,看起来像这样(简化):
{% label %} ... {% endlabel %}
"label"是用户可以自己定义的字母数字值,例如:
{% 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;
(一个块递归匹配文本或其他标签)
现在我正在侦听器中检查匹配项,但我希望我可以在解析器中进行匹配。有没有办法确保 ENDLABEL
在 Antlr4 的解析器级别等于 'end'
+ LABEL
?
... 如果我不在词法分析器中添加 'end' 是否可以做到这一点?
解析器在语法级别处理句法。您要求的内容无法用上下文无关语法 (CFG) 表达,这表明您无法在解析器级别解决此问题。
在您的方案中,我将创建一个强制执行您的语义的访问者。
ANTLR 4 可以为您生成抽象和基本访问者,然后您可以对其进行扩展。
创建两个额外的词法分析器规则
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
为真。
我正在匹配用户定义的 HTML-模板标签,看起来像这样(简化):
{% label %} ... {% endlabel %}
"label"是用户可以自己定义的字母数字值,例如:
{% 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;
(一个块递归匹配文本或其他标签)
现在我正在侦听器中检查匹配项,但我希望我可以在解析器中进行匹配。有没有办法确保 ENDLABEL
在 Antlr4 的解析器级别等于 'end'
+ LABEL
?
... 如果我不在词法分析器中添加 'end' 是否可以做到这一点?
解析器在语法级别处理句法。您要求的内容无法用上下文无关语法 (CFG) 表达,这表明您无法在解析器级别解决此问题。
在您的方案中,我将创建一个强制执行您的语义的访问者。 ANTLR 4 可以为您生成抽象和基本访问者,然后您可以对其进行扩展。
创建两个额外的词法分析器规则
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
为真。