【问题标题】:antlr grammar avoiding angle bracketsantlr 语法避免尖括号
【发布时间】:2016-09-01 18:55:53
【问题描述】:

this question 中,我询问了从任意文本中提取标签的问题。提供的解决方案效果很好,但我想处理一个极端情况。回顾一下,我正在解析任意用户输入的文本,并希望出现<> 以符合有效的标记语法。如果尖括号不是有效标签的一部分,则应将其转义为<>。我正在寻找的语法是<foo#123>,其中foo 是来自固定条目列表的文本,123 是一个数字[0-9]+。解析器:

parser grammar TagsParser;

options {
    tokenVocab = TagsLexer;
}

parse: (tag | text)* EOF;
tag: LANGLE fixedlist GRIDLET ID RANGLE;
text: NOANGLE;
fixedlist: FOO | BAR | BAZ;

词法分析器:

lexer grammar TagsLexer;

LANGLE: '<' -> pushMode(tag);
NOANGLE: ~[<>]+;

mode tag:

RANGLE: '>' -> popMode;
GRIDLET: '#';
FOO: 'foo';
BAR: 'bar';
BAZ: 'baz';
ID: [0-9]+;
OTHERTEXT: . ;

这很好用并且成功地解析了如下文本:

<foo#123>
Hi <bar#987>!
<baz#1><foo#2>anythinghere<baz#3>
if 1 &lt; 2

当我使用BailErrorStrategy时,它也成功地失败了:

<foo123>
<bar#a>
<foo#123H>
<unsupported#123>
if 1 < 2

最后一个成功失败,因为&amp;lt; 进入tag 模式并且它与支持的标记格式不匹配。但是,我也想避免在文本中出现 &amp;gt; 的实例,因此以下内容也应该失败:

if 2 > 1

该文本应指定为if 2 &amp;gt; 1,而不是使用原始尖括号。

如何修改语法以使不属于有效标签的&amp;gt; 的出现无法解析?

【问题讨论】:

  • 按照您现在的语法,标签之外的&amp;gt; 将导致标记识别错误,因为它在tag 模式之外的词法分析器语法中没有出现。这还不够吗?

标签: c# antlr antlr4 antlr4cs


【解决方案1】:

按照您现在的语法,它会在标记识别错误的标记之外失败&gt;,因为&gt; 不会出现在tag 模式之外的词法分析器语法中。这就是失败。但是如果你在 parse 期间坚持失败,那么只需在词法分析器的默认模式中添加直角:

lexer grammar TagsLexer;

LANGLE: '<' -> pushMode(tag);
NOANGLE: ~[<>]+;
BADRANGLE: '>';

mode tag;

RANGLE: '>' -> popMode;
...

那么标签外的&gt;会在解析时失败。

【讨论】:

  • 谢谢,这看似简单!看来我对这些东西的了解还有很长的路要走。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2011-09-28
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多