antlr4解析器能看到匹配的打开和关闭文本模式吗?

时间:2015-04-01 15:27:28

标签: parsing antlr4

我匹配的用户定义的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

...如果我没有在词法分析器中加上“结束”,是否可以这样做?

2 个答案:

答案 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可以为您生成抽象和基础访问者,然后您可以扩展它们。