当前位置: 首页 > 知识库问答 >
问题:

带有十进制数的ANTLR4语法问题

曹旭东
2023-03-14

我是ANTLR的新手,并使用ANTLR4(4.7.2 Jar文件)。我目前正在研究Oracle解析器。我对十进制数字有问题。我只保留了相关的部分。我的语法文件如下。

a NUMBER:= .1; // with Space after operator
a NUMBER:=1.1; // without Space after operator
a NUMBER:=1; // without Space after operator
a NUMER:= 3; // with Space after operator

我该怎么做?我尝试过使用_input.la(-1)!='.'}?等,但对我来说并不正确。我尝试了提到的许多其他步骤(大多数解决方案适用于ANTLR3,但不适用于ANTLR4)。在lexer中有没有一种简单的方法可以做到这一点?我不想编写解析器规则来拆分十进制数字。

grammar Oracle;

parse
 : ( sql_statements | error )* EOF
 ;

error
 : UNEXPECTED_CHAR 
 { 
    throw new RuntimeException("UNEXPECTED_CHAR=" + $UNEXPECTED_CHAR.text);
 }
 ;

sql_statements 
: 'CREATE' 'TABLESPACE' tablespace_name 'DATAFILE' fully_qualified_file_name ';'
| 'BEGIN' var1 'NUMBER' ':=' num1 ';' 'END' ';'
;

tablespace_name : IDENTIFIER;
fully_qualified_file_name : K_PLUS_SIGN diskgroup_name K_SOLIDUS db_name K_SOLIDUS file_type K_SOLIDUS file_type_tag '.' filenumber '.' incarnation_number;
diskgroup_name : IDENTIFIER;
db_name : IDENTIFIER;
file_type : IDENTIFIER;
file_type_tag : IDENTIFIER;
filenumber : NUMERIC_LITERAL;
incarnation_number : NUMERIC_LITERAL;

var1 : IDENTIFIER;
num1 : NUMERIC_LITERAL;

IDENTIFIER : [a-zA-Z_] ([a-zA-Z] | '$' | '_' | '#' | DIGIT)* ;
K_PLUS_SIGN : '+';
K_SOLIDUS : '/';
NUMERIC_LITERAL
 : DIGIT+ ( '.' DIGIT+ )? ( E ('+'|'-')? DIGIT+ )? ('D' | 'F')?
 | '.' DIGIT+ ( E ('+'|'-')? DIGIT+ )? ('D' | 'F')?
 ;

SPACES : [ \u000B\t\r\n] -> skip;
WS : [ \t\r\n]+ -> skip;
UNEXPECTED_CHAR : . ;

fragment DIGIT : [0-9];
fragment A : [aA];
fragment B : [bB];
fragment C : [cC];
fragment D : [dD];
fragment E : [eE];
fragment F : [fF];
fragment G : [gG];
fragment H : [hH];
fragment I : [iI];
fragment J : [jJ];
fragment K : [kK];
fragment L : [lL];
fragment M : [mM];
fragment N : [nN];
fragment O : [oO];
fragment P : [pP];
fragment Q : [qQ];
fragment R : [rR];
fragment S : [sS];
fragment T : [tT];
fragment U : [uU];
fragment V : [vV];
fragment W : [wW];
fragment X : [xX];
fragment Y : [yY];
fragment Z : [zZ];

共有1个答案

柳业
2023-03-14

您的Dsl有一个自然的模糊性:在某些情况下,数字是整数,而在其他情况下,数字是小数。

如果Dsl提供足够的保护条件,则可以使用Antlr模式来隔离实例。例如,在给定的Dsl中,十进制数字似乎总是出现在:=保护之间。

...
K_ASSIGN : ':=' -> pushMode(Decimals);
K_SEMI : ';' ;
NUMERIC_LITERAL : DIGIT+ ;
...
mode Decimals;
    D_SEMI : ';' -> type(K_SEMI), popMode ;
    NUMERIC: 
        DIGIT+ ( '.' DIGIT+ )? ( E ('+'|'-')? DIGIT+ )? 'D' 
        | 'F')? 
        | '.' DIGIT+ ( E ('+'|'-')? DIGIT+ )? ('D' | 'F')?
     -> type(NUMERIC_LITERAL);
 类似资料:
  • 我在调试一个ANTLR语法时遇到了问题,我正在为Gameboy程序集工作。它似乎工作正常,但由于某些原因,它不能在某些边缘情况下处理十六进制的0x表示法。 如果我的输入字符串是“JR0x10”,antlr将失败,并出现'No Valide alternative at input‘错误。按照我的理解,这意味着我要么没有解析令牌流的规则,要么没有正确理解'0x'。如果我使用“JR$10”(我支持的替

  • 问题内容: 小数dtype是否在numpy中可用? 我想numpy.array并不支持每个dtype,但是我认为只要定义正确的操作,它至少可以让dtype传播到尽可能远的距离。我想念什么吗?有什么办法可以工作吗? 问题答案: 重要提示:这是一个糟糕的答案 所以我在真正理解问题之前回答了这个问题。答案已被接受,并且有一些支持,但您最好跳至下一个。 原始答案: 似乎可用: 我不确定您要完成的工作,您的

  • 我在ANTLR4中有以下语法 一切都很好.我在语法1中哪里错了?

  • 我正在使用DecimalFormats将双打格式化为字符串。然后这个字符串被集成到我的表示层中。 问题:我想保留所有的小数。示例:“12345678.123456789” 格式:#.#- 我可以用##########对于大小数点,但是如果小数点更长呢? 我发现我的小测试程序很有用,想和大家分享。 你能帮我显示所有小数吗? 这导致: 编辑:一位用户提到了一个相关的问题:如何很好地将浮点数格式化为字符

  • 我有一个基于应用程序的计算器,我面临着两个十六进制基数之间的减法问题。如果是一个(大的数字减去一个小的数字),它会给出正确的结果。问题是当操作(小数字减去大数字)例如:(1-22或1a-22)应用程序崩溃并关闭时。 十六进制方法是: 除法运算的第二个问题是它给出了(结果=0),而不是0.12324,零后没有小数。 我如何解决这个代码?

  • 我对ANTLR相对来说是新的,所以请原谅我。 但是当我试图解析下面的表达式时 我最终出现以下错误: 第1:38行:'''处的令牌识别错误 第1:42行:'''处的令牌识别错误 规则r没有方法或者它有参数 规则'r'的意思是什么?我怎么能理解问题的原因呢?任何帮助都将不胜感激!