使用Antlr4分析简单模板



我正在尝试解析像he did [something called :action]这样的表达式,其中action是一个变量,括号表示块是可选的。如果括号内的一个变量丢失,那么我需要用像nothing这样的占位符来替换整个块。

我认为逻辑部分很简单,因为我熟悉访问者机制,但我无法解析字符串。

我尝试了下面的解析器,但它生成的是错误节点,而不是optionalParameter。我找不到问题,有人能看看这个解析脚本,告诉我我做错了什么吗?

grammar NamedParam;
query: (QUERY_CONTENT optionalParameter)*;
optionalParameter: '[' (STRING namedParameter)* ']';
namedParameter: ':' IDENTIFIER;
IDENTIFIER
: (ALPHANUMERIC)+;
fragment ALPHANUMERIC
: [A-Za-z0-9];
STRING : ~(':' | ']')* ;
QUERY_CONTENT : ~('[')* ;

您对ANTLR解析的理解似乎不完整:

ANTLR语法分析严格遵循ANTLR词法分析。在词法分析阶段,在不了解语法分析器规则的情况下,对完整的文本进行标记。如何生成令牌的规则是:

  • 更喜欢最长的令牌
  • 在两个匹配具有相同长度的情况下,首选第一个定义的令牌

您有三种令牌类型(我假设还有一个额外的空白规则):

he did [something called (-> STRING)
: (-> ':')
action] (-> QUERY_CONTENT)

您想要什么:解析器应该控制应该应用哪个令牌规则。

he did (->QUERY_CONTENT) 
...

但是这失败了,因为存在较长的令牌匹配CCD_。

避免包含其他代币的代币

  • 在和IDENTIFIER中添加一个不是:]的(非字母数字)字符(甚至是空格)会使生成的令牌成为字符串
  • 将非[的字符添加到STRING会使生成的令牌成为QUERY_CONTENT

有时这是不可避免的,但它会导致难以理解的解析错误的永久风险。

如何解决此问题:

  • 重写语法以适应ANTLR概念(如果你想保留这种语法,这可能很难实现)
  • 完善你的语言语法(更多的限制符号,非包含标记)
  • 使用PEG解析器(煮熟的老鼠)。这些类型的解析器非常接近您的理解

相关内容

  • 没有找到相关文章

最新更新