Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.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
Antlr ANLTR4:同时解析整数和浮点_Antlr_Antlr4 - Fatal编程技术网

Antlr ANLTR4:同时解析整数和浮点

Antlr ANLTR4:同时解析整数和浮点,antlr,antlr4,Antlr,Antlr4,我尝试使用ANLTR4解析两种类型的表达式: 对表达式是一对整数或浮点数字,如(1,2)或(1.0,2.0) 单个表达式是单个整数(1) 我的语法设计如下,但 如果在NUM之前写入INT,则无法将表达式与(1,2)等整数配对,因为需要NUM 如果我在INT之前写入NUM,则像(1)这样的单个表达式不能被标记化,因为需要INT 为了使这两个表达式都能够标记化,我可以删除NUMlexer并手动编写pair如下: pair : '(' INT ',' INT ')' | '('

我尝试使用ANLTR4解析两种类型的表达式:

  • 对表达式是一对整数或浮点数字,如
    (1,2)
    (1.0,2.0)
  • 单个表达式是单个整数
    (1)
  • 我的语法设计如下,但

    • 如果在
      NUM
      之前写入
      INT
      ,则无法将表达式与
      (1,2)
      等整数配对,因为需要
      NUM
    • 如果我在
      INT
      之前写入
      NUM
      ,则像
      (1)
      这样的单个表达式不能被标记化,因为需要
      INT
    为了使这两个表达式都能够标记化,我可以删除
    NUM
    lexer并手动编写
    pair
    如下:

    pair : '(' INT   ',' INT   ')'
         | '(' INT   ',' FLOAT ')'
         | '(' FLOAT ',' INT   ')'
         | '(' FLOAT ',' FLOAT ')'
         ;
    
    然后两个表达式都可以被解析,并且pair表达式同时支持整数和浮点

    但这很愚蠢,因为如果不是成对而是tuple10,就不可能写出1024个案例


    有更好的解决方案吗?

    正如kaby76已经作为注释提到的那样:将
    NUM
    升级为解析器规则。在lexer中定义
    INT
    FLOAT
    ,然后定义一个
    NUM
    ,使令牌
    INT
    FLOAT
    永远不会成为真正的令牌,这没有多大意义

    prog   : single | pair ;
    single : '(' INT ')' ;
    pair   : '(' num ',' num ')' ;
    num    : INT | FLOAT ;
    
    INT    : [0-9]+ ;
    FLOAT  : '-'? INT '.' INT ;
    WS     : [ \t\r\n] -> skip ;
    

    对将NUM提升到解析器级别,
    NUM:INT | FLOAT;tuple10:'('num,num,num,…'),并删除NUM。
    
    prog   : single | pair ;
    single : '(' INT ')' ;
    pair   : '(' num ',' num ')' ;
    num    : INT | FLOAT ;
    
    INT    : [0-9]+ ;
    FLOAT  : '-'? INT '.' INT ;
    WS     : [ \t\r\n] -> skip ;