Antlr4 解析键值IPV6对
我需要解析以下输入格式IP:FE80:CD00::211E:729C 解析后,我希望键为IP,值为FE80:CD00::211E:729C 我定义了以下语法Antlr4 解析键值IPV6对,antlr4,Antlr4,我需要解析以下输入格式IP:FE80:CD00::211E:729C 解析后,我希望键为IP,值为FE80:CD00::211E:729C 我定义了以下语法 grammar IPV6; keyValue : KEY ip_v6_address; ip_v6_address : h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' ls32 | '::' h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' ls32 |
grammar IPV6;
keyValue : KEY ip_v6_address;
ip_v6_address
: h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' ls32
| '::' h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' ls32
| h16? '::' h16 ':' h16 ':' h16 ':' h16 ':' ls32
| ((h16 ':')? h16)? '::' h16 ':' h16 ':' h16 ':' ls32
| (((h16 ':')? h16 ':')? h16)? '::' h16 ':' h16 ':' ls32
| ((((h16 ':')? h16 ':')? h16 ':')? h16)? '::' h16 ':' ls32
| (((((h16 ':')? h16 ':')? h16 ':')? h16 ':')? h16)? '::' ls32
| ((((((h16 ':')? h16 ':')? h16 ':')? h16 ':')? h16 ':')? h16)? '::' h16
;
h16
: hexdig hexdig hexdig hexdig
| hexdig hexdig hexdig
| hexdig hexdig
| hexdig
;
hexdig
: digit
| (A | B | C | D | E | F)
;
ls32
: h16 ':' h16
| ip_v4_address
;
ip_v4_address
: dec_octet '.' dec_octet '.' dec_octet '.' dec_octet
;
dec_octet
: digit
| non_zero_digit digit
| D1 digit digit
| D2 (D0 | D1 | D2 | D3 | D4) digit
| D2 D5 (D0 | D1 | D2 | D3 | D4 | D5)
;
digit
: D0
| non_zero_digit
;
non_zero_digit
: D1
| D2
| D3
| D4
| D5
| D6
| D7
| D8
| D9
;
D0 : '0';
D1 : '1';
D2 : '2';
D3 : '3';
D4 : '4';
D5 : '5';
D6 : '6';
D7 : '7';
D8 : '8';
D9 : '9';
A : 'a'|'A';
B : 'b'|'B';
C : 'c'|'C';
D : 'd'|'D';
E : 'e'|'E';
F : 'f'|'F';
KEY: '['? STRING SPACE* STRING']'?':';
fragment SPACE : ' ';
fragment STRING: [a-zA-Z0-9/._-]+;
WS : [ \t\r\n] + -> skip;
在针对上面的示例运行之后,上面的语法为我提供了以下标记
[TOKENS]
KEY 'IP:'
KEY 'FE80:'
KEY 'CD00:'
':' ':'
KEY '211E:'
D7 '7'
D2 '2'
D9 '9'
C 'C'
EOF '<EOF>'
[PARSE-TREE]
line 1:3 mismatched input 'FE80:' expecting {'::', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', A, B, C, D, E, F}
(keyValue IP:
(ip_v6_address FE80: CD00: : 211E: 7 2 9 C))
[令牌]
密钥“IP:”
键“FE80:”
键“CD00:”
':' ':'
键“211E:”
D7'7'
D2‘2’
D9'9'
C'C'
EOF“
[解析树]
第1:3行不匹配的输入'FE80:'应为{':','0','1','2','3','4','5','6','7','8','9',A,B,C,D,E,F}
(键值IP:
(ip地址FE80:CD00::211E:729 C))
我希望将键值对作为输出,但不确定是否编写了正确的语法。我面临的问题是分隔符“:”也可以在值中退出。
任何关于如何修复语法的指针吗?由于词法规则重叠(多个规则匹配同一输入),它不起作用 来自
FE80:
的F
字符未被标记为十六进制数字(《F
lexer规则》)。但是,整个区块FE80:
被标记为键
标记
您必须意识到lexer独立于解析器运行。解析器可能试图匹配某个标记,但lexer不会“侦听”该标记。lexer遵循两条非常简单的规则:
F
标记为F
标记,但像FE
这样的输入标记为键
标记
解决方案是将键
的构造从lexer移动到键
解析器规则,如下所示:
grammar IPV6;
key_value
: key ':' ip_v6_address
;
key
: '[' string ']'
| string
;
ip_v6_address
: h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' ls32
| '::' h16 ':' h16 ':' h16 ':' h16 ':' h16 ':' ls32
| h16? '::' h16 ':' h16 ':' h16 ':' h16 ':' ls32
| ((h16 ':')? h16)? '::' h16 ':' h16 ':' h16 ':' ls32
| (((h16 ':')? h16 ':')? h16)? '::' h16 ':' h16 ':' ls32
| ((((h16 ':')? h16 ':')? h16 ':')? h16)? '::' h16 ':' ls32
| (((((h16 ':')? h16 ':')? h16 ':')? h16 ':')? h16)? '::' ls32
| ((((((h16 ':')? h16 ':')? h16 ':')? h16 ':')? h16 ':')? h16)? '::' h16
;
h16
: hexdig hexdig hexdig hexdig
| hexdig hexdig hexdig
| hexdig hexdig
| hexdig
;
hexdig
: digit
| (A | B | C | D | E | F)
;
ls32
: h16 ':' h16
| ip_v4_address
;
ip_v4_address
: dec_octet '.' dec_octet '.' dec_octet '.' dec_octet
;
dec_octet
: digit
| non_zero_digit digit
| D1 digit digit
| D2 (D0 | D1 | D2 | D3 | D4) digit
| D2 D5 (D0 | D1 | D2 | D3 | D4 | D5)
;
digit
: D0
| non_zero_digit
;
non_zero_digit
: D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9
;
string
: (STRING_ATOM | hexdig)+
;
D0 : '0';
D1 : '1';
D2 : '2';
D3 : '3';
D4 : '4';
D5 : '5';
D6 : '6';
D7 : '7';
D8 : '8';
D9 : '9';
A : [aA];
B : [bB];
C : [cC];
D : [dD];
E : [eE];
F : [fF];
STRING_ATOM : [g-zG-Z/._-];
WS : [ \t\r\n] + -> skip;
生成以下解析树: