gpt4 book ai didi

antlr - 另一个没有可行的替代方案...

转载 作者:行者123 更新时间:2023-12-04 05:17:49 26 4
gpt4 key购买 nike

我有一个类似于在线教程中的数学表达式语法文件:http://javadude.com/articles/antlr3xtut/

但是现在我想为函数添加选项,但我很难让词法分析器/解析器规则正常工作。我可以使用丑陋的词法分析器规则来使代码正常工作,但我想使用更干净的标记来使解析器规则正常工作。

如果我尝试这样做,对于像 'a*b/13.2*Test(3,2)' 这样的表达式,我会在输入 'Test('"时捕获“第 1:9 行没有可行的替代方案”异常

请检查以下语法文件中的注释以了解我的确切问题是什么

grammar ExpressionOnly;

options {
language = Java;
}

@header {
package kic.engine.grammar;
}

@lexer::header {
package kic.engine.grammar;
}


// Top Rule
eval
: expression
;

term
: func
| '(' op1=expression ')'
| array
| element
;

// Sub Terms
func
// : f=FUNC // Works but this is very ugly because FUNC contains '(';
: f=IDENT '(' // <---------------------------- why does this not work: line 1:9 no viable alternative at input 'Test('
(arg=expression (',' arg=expression)*)?
')'
;

array
: '[' ele=element (',' ele=element)* ']'
;

element
: b=(K_TRUE | K_FALSE)
| NUMBER
| IDENT
| DATE
| SQ_STRING
| K_NULL
;

negation
@init{ boolean negate = false; }
: (K_NOT | '!' { negate = true;} )?
term
;

unary
@init{ boolean positive = true; }
: ('+' | '-')*
negation
;

power
: op1=unary
( '^' op2=unary
)*
;

multiply
: op1=power
( '*' op2=power
| '/' op2=power
| '%' op2=power
)*
;

add
: op1=multiply
( '+' op2=multiply
| '-' op2=multiply
)*
;

relation
: op1=add
( '=' op2=add
| '!=' op2=add
| '<' op2=add
| '<=' op2=add
| '>' op2=add
| '>=' op2=add
)*
;

expression
: op1=relation
( (K_AND | '&') op2=relation
| (K_OR | '|') op2=relation
)*
;


// Case-insensitive alpha characters
fragment A: ('a'|'A');
fragment B: ('b'|'B');
fragment C: ('c'|'C');
fragment D: ('d'|'D');
fragment E: ('e'|'E');
fragment F: ('f'|'F');
fragment G: ('g'|'G');
fragment H: ('h'|'H');
fragment I: ('i'|'I');
fragment J: ('j'|'J');
fragment K: ('k'|'K');
fragment L: ('l'|'L');
fragment M: ('m'|'M');
fragment N: ('n'|'N');
fragment O: ('o'|'O');
fragment P: ('p'|'P');
fragment Q: ('q'|'Q');
fragment R: ('r'|'R');
fragment S: ('s'|'S');
fragment T: ('t'|'T');
fragment U: ('u'|'U');
fragment V: ('v'|'V');
fragment W: ('w'|'W');
fragment X: ('x'|'X');
fragment Y: ('y'|'Y');
fragment Z: ('z'|'Z');


// Fragments
fragment DIGIT : '0' .. '9';
fragment UPPER : 'A' .. 'Z';
fragment LOWER : 'a' .. 'z';
fragment LETTER : LOWER | UPPER;
fragment WORD : LETTER | '_' | '$' | '#' | '.';
fragment ALPHANUM : WORD | DIGIT;
fragment ESCAPE[StringBuilder buf] :
'\\'
( 't' { buf.append('\t'); }
| 'n' { buf.append('\n'); }
| 'r' { buf.append('\r'); }
| '"' { buf.append('\"'); }
| '\\' { buf.append('\\'); }
)
;

// Keyowords
K_FALSE : F A L S E;
K_NULL : N U L L;
K_TRUE : T R U E;
K_AND : A N D;
K_NOT : N O T;
K_OR : O R;

// Tokens;
FUNC : LETTER+ '(';

IDENT : LETTER ALPHANUM*;

ARRAY_INDEX : IDENT '[';

DQ_STRING
@init { final StringBuilder buf = new StringBuilder(); }
: '"'
( ESCAPE[buf]
| i = ~('\\' | '"') { buf.appendCodePoint(i); }
)*
{ setText(buf.toString()); }
;

NUMBER: DIGIT+ ('.' DIGIT+)? (('e'|'E')('+'|'-')? DIGIT+)?;

DATE: '\'' DIGIT DIGIT DIGIT DIGIT '-' DIGIT DIGIT '-' DIGIT DIGIT (' ' DIGIT DIGIT ':' DIGIT DIGIT ':' DIGIT DIGIT ('.' DIGIT+)?)? '\'';

SQ_STRING : '\'' .* '\'';

// hidden tokens
WS : (' ' | '\t' | '\r' | '\n')+ {$channel=HIDDEN;};

COMMENTS : '/*' .* '*/' {$channel=HIDDEN;};

任何想法如何让函数规则与 IDENT token 一起工作?

最佳答案

输入 Test(3,2)变成以下 token :

[FUNC : Test(] [NUMBER : 3] [',' : ,] [NUMBER : 2] [')' : )] 

当前没有解析器规则需要 FUNC token ,所以解析器产生一个错误,打印 token 的内容: line 2:1 no viable alternative at input 'Test(' .

注释掉 FUNC词法分析器规则,重新生成所有内容,然后重新运行。现在相同的输入产生这些标记没有错误:
[IDENT : Test] ['(' : (] [NUMBER : 3] [',' : ,] [NUMBER : 2] [')' : )] 

出于测试目的,我将语法输出设为 AST 并更改了术语 f=IDENT在解析器规则中 funcf=IDENT^ , 以便更容易地在 AST 中查看解析器是否识别出一个函数。

现在,输入 a*b/13.2*Test(3,2)我得到以下 AST:

AST

输入 Test(3,2)被正确识别为函数,并相应地生成 AST。

关于antlr - 另一个没有可行的替代方案...,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14031966/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com