使用 Antlr4 解析简单模板
Parsing simple template with Antlr4
我正在尝试解析像 he did [something called :action]
这样的表达式,其中 action 是一个变量,括号表示该块是可选的。如果括号内的变量之一丢失,那么我需要用 nothing
.
这样的占位符替换整个块
我认为逻辑部分很简单,因为我熟悉访问者机制,但我无法解析字符串。
我尝试了以下解析器,但它生成错误节点而不是可选参数。我找不到问题,谁能看看这个解析脚本并告诉我我做错了什么?
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 词法分析。在词法分析阶段,完整的文本在不知道解析器规则的情况下被标记化。生成token的规则是:
- 喜欢最长的令牌
- 如果两个匹配长度相同,则首选第一个定义的标记
你有三种标记类型(我假设还有一个额外的空白规则):
he did [something called (-> STRING)
: (-> ':')
action] (-> QUERY_CONTENT)
你想要什么:解析器应该控制应该应用哪个令牌规则。
he did (->QUERY_CONTENT)
...
但这失败了,因为存在更长的令牌匹配 he did [something called
。
避免包含其他标记的标记
- 将不是
:
或 ]
的(非字母数字)字符(甚至是空格)添加到 IDENTIFIER 中,使生成的标记成为 STRING。
- 将非
[
的字符添加到 STRING 会使生成的标记成为 QUERY_CONTENT
有时无法避免,但它会导致难以理解的解析错误的永久风险。
如何解决:
- 重写你的语法以适应 ANTLR 概念(如果你想保留这种语法,这可能很难实现)
- 改进您的语言语法(更多限制符号、非归并标记)
- 使用 PEG 解析器(煮熟的大鼠)。这些类型的解析器非常接近您的理解。
我正在尝试解析像 he did [something called :action]
这样的表达式,其中 action 是一个变量,括号表示该块是可选的。如果括号内的变量之一丢失,那么我需要用 nothing
.
我认为逻辑部分很简单,因为我熟悉访问者机制,但我无法解析字符串。
我尝试了以下解析器,但它生成错误节点而不是可选参数。我找不到问题,谁能看看这个解析脚本并告诉我我做错了什么?
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 词法分析。在词法分析阶段,完整的文本在不知道解析器规则的情况下被标记化。生成token的规则是:
- 喜欢最长的令牌
- 如果两个匹配长度相同,则首选第一个定义的标记
你有三种标记类型(我假设还有一个额外的空白规则):
he did [something called (-> STRING)
: (-> ':')
action] (-> QUERY_CONTENT)
你想要什么:解析器应该控制应该应用哪个令牌规则。
he did (->QUERY_CONTENT)
...
但这失败了,因为存在更长的令牌匹配 he did [something called
。
避免包含其他标记的标记
- 将不是
:
或]
的(非字母数字)字符(甚至是空格)添加到 IDENTIFIER 中,使生成的标记成为 STRING。 - 将非
[
的字符添加到 STRING 会使生成的标记成为 QUERY_CONTENT
有时无法避免,但它会导致难以理解的解析错误的永久风险。
如何解决:
- 重写你的语法以适应 ANTLR 概念(如果你想保留这种语法,这可能很难实现)
- 改进您的语言语法(更多限制符号、非归并标记)
- 使用 PEG 解析器(煮熟的大鼠)。这些类型的解析器非常接近您的理解。