我想使用 ANTLR 工具为下面的 yaml 示例文件生成嵌套解析树。 我尝试了下面的语法文件,但由于某种原因,它没有根据 yaml 文件正确显示嵌套 od 节点。
yaml 文件是:
kind: Test
metadata:
name: target
labels:
runnable: target
annotations:
message_value: Hi
id: 1
node_id: 2
hex_id: 3
我尝试过的antlr语法是:
grammar Sample;
yaml: (entry NEWLINE)* EOF;
entry: (keyValue | mapping);
keyValue: SPACE* KEY COLON SPACE* value SPACE* NEWLINE;
mapping: SPACE* KEY COLON SPACE* NEWLINE (nestedEntry)+;
nestedEntry: SPACE* keyValue | mapping;
value: STRING | NUMBER | (NEWLINE SPACE* mapping);
KEY: [a-zA-Z_]+[0-9]*[a-zA-Z_]*;
STRING: [a-zA-Z._]+;
NUMBER: [0-9]+;
NEWLINE: [\r\n]+;
SPACE: [ ] -> skip;
COLON: ':' -> skip;
预期的解析树输出如下:
我怎样才能实现这个正确的解析树。
知道上面语法中的这个问题是什么以及如何解决这个问题吗?
您的
KEY
和 STRING
规则重叠太多,导致 STRING
几乎永远不会匹配。使用 ANTLR,当 2 个(或更多)规则匹配相同时,第一个定义的规则“获胜”。因此 Test
、target
和 hi
不会匹配为 STRING
,而是匹配为 KEY
。
此外,您在词法分析器中跳过
SPACE
和 COLON
,使它们在解析器规则中不可用。 COLON
一开始就不应该被跳过。
尝试这样的事情:
yaml: entry (NEWLINE+ entry)* NEWLINE* EOF;
entry: (keyValue | mapping);
keyValue: KEY COLON value;
mapping: KEY COLON NEWLINE (nestedEntry)+;
nestedEntry: keyValue | mapping;
value: KEY | NUMBER | (NEWLINE mapping);
KEY: [a-zA-Z_]+[0-9]*[a-zA-Z_]*;
NUMBER: [0-9]+;
NEWLINE: [\r\n]+;
SPACE: [ \t] -> skip;
COLON: ':';
它将像这样解析您的示例输入:
我相信您已经意识到这一点,但由于缩进,为 YAML 编写 ANTLR 语法相当棘手。您可以在这里查看:https://github.com/umaranis/FastYaml