Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Antlr4 解析键值IPV6对_Antlr4 - Fatal编程技术网

Antlr4 解析键值IPV6对

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 |

我需要解析以下输入格式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
 | 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;
    
    生成以下解析树: