我为表达式语言定义了一个语法,实际上它更复杂,但我简化了这里,我定义了一些函数来为Java翻译这个表达式(我不使用Java语法,我只是翻译成字符串)。我在语法中定义了一些常量(我不知道它是否是正确的名称),它调用" MAXINT"和" MININT",以及一些调用translateExp将我在语法中定义的每个表达式转换为字符串的函数。我尝试翻译的大多数表达都有效,但是当" MAXINT"或" MININT"表达式中出现不起作用并抛出UnsupportedOperationException并且我不知道为什么,例如" MAXINT - 1"。有人知道为什么,可以帮助我吗?抛出UnsupportedOperationException的另一个问题是当我尝试翻译一些具有多个加号(+)或减号( - )的表达式时,例如" 1 + 1 + 1"再次,有人知道为什么?
我的模块包含语法和功能:
module ExpSyntax
import String;
import ParseTree;
layout Whitespaces = [\t\n\ \r\f]*;
lexical Ident = [a-z A-Z 0-9 _] !<< [a-z A-Z][a-z A-Z 0-9 _]* !>> [a-z A-Z 0-9 _] \ Keywords;
lexical Integer_literal = [0-9]+;
keyword Keywords = "MAXINT" | "MININT";
start syntax Expression
= Expressions_primary
| Expressions_arithmetical;
syntax Expressions_primary
= Data: Ident+ id
| bracket Expr_bracketed: "(" Expression e ")"
;
syntax Expressions_arithmetical
= Integer_lit
| left Addition: Expression e1 "+" Expression e2
| left Difference: Expression e1 "-" Expression e2
;
syntax Integer_lit
= Integer_literal il
| MAX_INT: "MAXINT"
| MIN_INT: "MININT"
;
public str translate(str txt) = translateExp(parse(#Expression, txt));
public str translateExp((Expression) `<Integer_literal i>`) = "<i>";
public str translateExp((Expression) `MAXINT`) = "java.lang.Integer.MAX_VALUE";
public str translateExp((Expression) `MININT`) = "java.lang.Integer.MIN_VALUE";
public str translateExp((Expression) `<Expression e1>+<Expression e2>`) = "<translateExp(e1)> + <translateExp(e2)>";
public str translateExp((Expression) `<Expression e1>-<Expression e2>`) = "<translateExp(e1)> - <translateExp(e2)>";
public str translateExp((Expression) `<Ident id>`) = "<id>";
public str translateExp((Expression) `(<Expression e>)`) = "(<translateExp(e)>)";
这就是:
rascal>import ExpSyntax;
ok
rascal>translate("(test + 1) - test2");
str: "(test + 1) - test2"
rascal>translate("MAXINT - 1");
java.lang.UnsupportedOperationException(internal error) at $shell$(|main://$shell$|)
java.lang.UnsupportedOperationException
at org.rascalmpl.ast.Expression.getKeywordArguments(Expression.java:214)
at org.rascalmpl.interpreter.matching.NodePattern.<init>(NodePattern.java:84)
at org.rascalmpl.semantics.dynamic.Tree$Amb.buildMatcher(Tree.java:351)
at org.rascalmpl.ast.AbstractAST.getMatcher(AbstractAST.java:173)
at org.rascalmpl.interpreter.result.RascalFunction.prepareFormals(RascalFunction.java:503)
at org.rascalmpl.interpreter.result.RascalFunction.call(RascalFunction.java:365)
at org.rascalmpl.interpreter.result.OverloadedFunction.callWith(OverloadedFunction.java:327)
at org.rascalmpl.interpreter.result.OverloadedFunction.call(OverloadedFunction.java:305)
at org.rascalmpl.semantics.dynamic.Expression$CallOrTree.interpret(Expression.java:486)
at org.rascalmpl.semantics.dynamic.Statement$Expression.interpret(Statement.java:355)
at org.rascalmpl.semantics.dynamic.Statement$Return.interpret(Statement.java:773)
at org.rascalmpl.interpreter.result.RascalFunction.runBody(RascalFunction.java:467)
at org.rascalmpl.interpreter.result.RascalFunction.call(RascalFunction.java:413)
at org.rascalmpl.interpreter.result.OverloadedFunction.callWith(OverloadedFunction.java:327)
at org.rascalmpl.interpreter.result.OverloadedFunction.call(OverloadedFunction.java:305)
at org.rascalmpl.semantics.dynamic.Expression$CallOrTree.interpret(Expression.java:486)
at org.rascalmpl.semantics.dynamic.Statement$Expression.interpret(Statement.java:355)
at org.rascalmpl.interpreter.Evaluator.eval(Evaluator.java:936)
at org.rascalmpl.semantics.dynamic.Command$Statement.interpret(Command.java:115)
at org.rascalmpl.interpreter.Evaluator.eval(Evaluator.java:1147)
at org.rascalmpl.interpreter.Evaluator.eval(Evaluator.java:1107)
at org.rascalmpl.eclipse.console.RascalScriptInterpreter.execCommand(RascalScriptInterpreter.java:446)
at org.rascalmpl.eclipse.console.RascalScriptInterpreter.run(RascalScriptInterpreter.java:239)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
rascal>translate("1+1+1");
java.lang.UnsupportedOperationException(internal error) at $shell$(|main://$shell$|)
java.lang.UnsupportedOperationException
at org.rascalmpl.ast.Expression.getKeywordArguments(Expression.java:214)
at org.rascalmpl.interpreter.matching.NodePattern.<init>(NodePattern.java:84)
at org.rascalmpl.semantics.dynamic.Tree$Amb.buildMatcher(Tree.java:351)
at org.rascalmpl.ast.AbstractAST.getMatcher(AbstractAST.java:173)
at org.rascalmpl.interpreter.result.RascalFunction.prepareFormals(RascalFunction.java:503)
at org.rascalmpl.interpreter.result.RascalFunction.call(RascalFunction.java:365)
at org.rascalmpl.interpreter.result.OverloadedFunction.callWith(OverloadedFunction.java:327)
at org.rascalmpl.interpreter.result.OverloadedFunction.call(OverloadedFunction.java:305)
at org.rascalmpl.semantics.dynamic.Expression$CallOrTree.interpret(Expression.java:486)
at org.rascalmpl.semantics.dynamic.Statement$Expression.interpret(Statement.java:355)
at org.rascalmpl.semantics.dynamic.Statement$Return.interpret(Statement.java:773)
at org.rascalmpl.interpreter.result.RascalFunction.runBody(RascalFunction.java:467)
at org.rascalmpl.interpreter.result.RascalFunction.call(RascalFunction.java:413)
at org.rascalmpl.interpreter.result.OverloadedFunction.callWith(OverloadedFunction.java:327)
at org.rascalmpl.interpreter.result.OverloadedFunction.call(OverloadedFunction.java:305)
at org.rascalmpl.semantics.dynamic.Expression$CallOrTree.interpret(Expression.java:486)
at org.rascalmpl.semantics.dynamic.Statement$Expression.interpret(Statement.java:355)
at org.rascalmpl.interpreter.Evaluator.eval(Evaluator.java:936)
at org.rascalmpl.semantics.dynamic.Command$Statement.interpret(Command.java:115)
at org.rascalmpl.interpreter.Evaluator.eval(Evaluator.java:1147)
at org.rascalmpl.interpreter.Evaluator.eval(Evaluator.java:1107)
at org.rascalmpl.eclipse.console.RascalScriptInterpreter.execCommand(RascalScriptInterpreter.java:446)
at org.rascalmpl.eclipse.console.RascalScriptInterpreter.run(RascalScriptInterpreter.java:239)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
答案 0 :(得分:0)
错误消息是一个错误,因为它应该报告更清楚的内容,但似乎您的语法定义仍然存在歧义。运行时正在尝试为Tree$Amb
(org.rascalmpl.semantics.dynamic.Tree$Amb.buildMatcher
)构建模式匹配器,我们没有实现这些匹配器并且不会实现。
从查看定义(我没有尝试过),似乎原因就是这个规则:
lexical Ident = [a-z A-Z 0-9 _] !<< [a-z A-Z][a-z A-Z 0-9 _]* !>> [a-z A-Z 0-9 _] \ Keywords;
由于!>>
和\
绑定比并置更强,\
关键字预留仅适用于Ident
的尾部,而不是整个。{1}}。请添加括号(序列运算符)以消除歧义:
lexical Ident = [a-z A-Z 0-9 _] !<< ([a-z A-Z][a-z A-Z 0-9 _]*) !>> [a-z A-Z 0-9 _] \ Keywords;
这可以让你更进一步。
然后你的表达式语法仍然含糊不清,可以简化为:
start syntax Expression
= Data: Ident+ id
| Integer: Integer_lit
| bracket bracketed: "(" Expression e ")"
> left
( Addition: Expression e1 "+" Expression e2
| Difference: Expression e1 "-" Expression e2
)
;
syntax Integer_lit
= Integer_literal il
| MAX_INT: "MAXINT"
| MIN_INT: "MININT"
;
简短说明:left
仅适用于直接递归的非终端。由于您根据Expressions_arithmatical
定义了Expression
,因此没有直接递归。下一个将支持间接递归,但对于这个语法,这是不必要的。
另外,我补充说+
和-
通过将它们放在一个组中而相互保留递归,否则1+1-1
将保持不明确。