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 为真。