ANTLR4语法开始出现';和';和';或';以变量名
请帮助我学习ANTLR4语法 样本“formel”:ANTLR4语法开始出现';和';和';或';以变量名,antlr4,Antlr4,请帮助我学习ANTLR4语法 样本“formel”: (Arbejde.ArbejderIKommuneNr=860)和(Arbejde.ErIArbejde='J')& (Arbejde.ArbejdsTimerPrUge=40) (Ansogeren.BorIKommunen='J')和(BeregnDato)(Ansogeren.Fodselsdato; “+62Å”)
- (Arbejde.ArbejderIKommuneNr=860)和(Arbejde.ErIArbejde='J')& (Arbejde.ArbejdsTimerPrUge=40)
- (Ansogeren.BorIKommunen='J')和(BeregnDato)(Ansogeren.Fodselsdato;
“+62Å”)
- (平均BorI=860)
- 错误:在第行输入“(Arb.Bor)”处没有可行的备选方案/位置:1/6\r\n异常:Der blev udløst en undtagelse af typen'Antlr4.Runtime.noviablealException
grammar UnikFormel;
formel : boolExpression # BooleanExpr
| expression # Expr
| '(' formel ')' # Parentes;
boolExpression : ( '(' expression ')' ) ( booleanOps '(' expression ')' )+;
expression : element compareOps element # Compare;
element : datakildefelt # DatakildeId
| function # Funktion
| int # Integer
| decimal # Real
| string # Text;
datakildefelt : datakilde '.' felt;
datakilde : identifyer;
felt : identifyer;
function : funktionsnavn ('(' funcParameters? ')')?;
funktionsnavn : identifyer;
funcParameters : funcParameter (';' funcParameter)*;
funcParameter : element;
identifyer : LETTER+;
int : DIGIT+;
decimal : DIGIT+ '.' DIGIT+ | '.' DIGIT+;
string : QUOTE .*? QUOTE;
booleanOps : (AND | OR);
compareOps : (LT | GT | EQ | GTEQ | LTEQ);
QUOTE : '\'';
OPERATOR: '+';
DIGIT: [0-9];
LETTER: [a-åA-Å];
MUL : '*';
DIV : '/';
ADD : '+';
SUB : '-';
GT : '>';
LT : '<';
EQ : '=';
GTEQ : '>=';
LTEQ : '<=';
AND : '&' | 'and';
OR : '?' | 'or';
WS : ' '+ -> skip;
语法统一格式;
formel:boolExpression#BooleanExpr
|表达式#Expr
|"("formel")"父母,;
boolExpression:('('expression'))(booleanOps'('expression'))+;
表达式:element compareOps element#Compare;
元素:datakildefelt#DatakildeId
|功能#功能
|整数
|十进制#实数
|字符串#文本;
datakildefelt:datakilde'.'毡;
datakilde:标识符;
毛毡:识别器;
函数:funktionsnavn('('funcParameters?'))?;
funktionsnavn:识别器;
funcParameters:funcParameter(“;”funcParameter)*;
funcParameter:元素;
标识符:字母+;
整数:数字+;
十进制:数字+'.'数字+|'.'数字+;
字符串:QUOTE.*?QUOTE;
布尔运算:(和|或);
比较:(LT | GT | EQ | GTEQ | LTEQ);
引号:“\”;
运算符:'+';
数字:[0-9];
信:[a-åa-Å];
MUL:“*”;
分区:“/”;
加:“+”;
SUB:“-”;
GT:“>”;
LT:'=';
LTEQ:“先到的规则总是有优先权的。在你的情况下,你需要将和和或移到字母之前。另外GTEQ和LTEQ
也有同样的问题,可能在其他地方
编辑
此外,您应该将IDENTIFIER
作为词法规则,即以大写字母开头(IDENTIFIER
或IDENTIFIER
)。对于int
、decimal
和string
也是如此。输入最初是一个字符流,首先只使用lexer规则处理为一个令牌流。此时,解析器规则(以小写字母开头的规则)还没有发挥作用。因此,让“BorI”作为单个实体(令牌)进行解析,您需要创建一个与标识符匹配的lexer规则。目前,它将被解析为3个标记:字母
(B)或(或)字母
(I)。感谢您的帮助。出现了多个问题。阅读ANTLR4手册并使用“TestRig-gui”使我走上了正确的道路。工作语法是:
grammar UnikFormel;
formel : '(' formel ')' # Parentes
| expression # Expr
| boolExpression # BooleanExpr
;
boolExpression : '(' expression ')' ( booleanOps '(' expression ')' )+
| '(' formel ')' ( booleanOps '(' formel ')' )+;
expression : element compareOps element # Compare;
datakildefelt : ID '.' ID;
function : ID ('(' funcParameters? ')')?;
funcParameters : funcParameter (';' funcParameter)*;
funcParameter : element;
element : datakildefelt # DatakildeId
| function # Funktion
| INT # Integer
| DECIMAL # Real
| STRING # Text;
booleanOps : (AND | OR);
compareOps : ( GTEQ | LTEQ | LT | GT | EQ |);
AND : '&' | 'and';
OR : '?' | 'or';
GTEQ : '>=';
LTEQ : '<=';
GT : '>';
LT : '<';
EQ : '=';
ID : LETTER ( LETTER | DIGIT)*;
INT : DIGIT+;
DECIMAL : DIGIT+ '.' DIGIT+ | '.' DIGIT+;
STRING : QUOTE .*? QUOTE;
fragment QUOTE : '\'';
fragment DIGIT: [0-9];
fragment LETTER: [a-åA-Å];
WS : [ \t\r\n]+ -> skip;
语法统一格式;
formel:“(“formel”)”父母
|表达式#Expr
|boolExpression#BooleanExpr
;
boolExpression:'('expression')'(booleanOps'('expression'))+
|“('formel')”(booleanOps“('formel'))+;
表达式:element compareOps element#Compare;
datakildefelt:ID'.'ID;
函数:ID(“('funcParameters?)”)?;
funcParameters:funcParameter(“;”funcParameter)*;
funcParameter:元素;
元素:datakildefelt#DatakildeId
|功能#功能
|整数
|十进制#实数
|字符串#文本;
布尔运算:(和|或);
比较:(GTEQ | LTEQ | LT | GT | EQ |);
及:"&|"及";;
或:“?”|“或”;
GTEQ:“>=”;
LTEQ:“”;
LT:“跳过;
如果您通过将表达式
的两个匹配项都更改为formel
,然后将+
更改为*
中的*
来删除formel
中的第三行,会怎么样?我不认为Arb.Borl中的或
是一个问题,因为这样您在工作示例中就有了或好的。谢谢你的建议。很抱歉,但没有起到作用。我尝试在gramar和测试数据中将“or”改为“oor”和“and”和“aand”;(Arbejde.ArbejderIKommuneNr=860)oor(Arbejde.ErIArbejde=“J”)和:“&”|“aand”或“?”|“oor”;然后它就起作用了。但我需要“and”和“or”:-(谢谢你的建议。我尝试了:和:“&”&“|”和“;或:”?“|”或“;GTEQ:”>=”;LTEQ:”;LT:“跳过;
,但它并没有改变结果。如果异常文本不是用我不懂的语言编写的,也许我可以帮助更多。谢谢你的帮助。我已经尝试翻译错误:错误:目前没有可行的替代方案输入'(Arb.Bor'在行号/位置:1/6异常:引发了类型为'Antlr4.Runtime.NoViableAltException'的Ab异常。另外,我正在运行Antlr4.Runtime.net45。我正在将基于Delphi的旧系统迁移到.net中-在旧系统中,用户可以输入计算为真或假的业务规则'formel'。我就是这个计算程序使用ANTLR实现(我已经让访问者运行了,但是我需要'datakildefelt'-我从解析器中得到它-因为我需要在需要时向访问者提供实际值(大多数'datakildefelt'指的是数据库表的字段)1.我希望我的译文是正确的,希望你能更好地理解我在做什么。