在Irony中定义常量和操作符
本文关键字:操作符 常量 定义 Irony | 更新日期: 2023-09-27 18:04:09
我对Irony和整个语言实现都不熟悉,所以我一直在使用Irony源代码附带的ExpressionEvaluator示例,它似乎(几乎)适合我正在进行的项目的需要。
但是,我希望它也支持布尔值,所以我在二进制操作符列表中添加了比较操作符,如下所示:
BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**"
| "==" | "<=" | ">=" | "<" | ">" | "!=" | "<>"; // added comparison operators
下面是我想要实现的一个例子:
x = 1
y = 2
eval = x < 2
eval2 = y < x
bool = true
bool2 = (eval == eval2)
由于添加了二进制操作符,因此可以成功解析上述内容。但是,在编译和运行代码时,它在最后两行失败。
-
bool = true
行失败,提示信息:Error: Variable true not defined。(8)。如何定义true和false作为常量? -
bool2 = (eval == eval2)
行失败,出现以下消息:错误:Operator '=='未为System类型定义。Boolean和System.Boolean。(15)。
编辑:两个问题都解决了,见下面的答案
好了,两个问题都解决了。希望能对别人有所帮助。
一号据我所知,从这个Irony讨论线程中,true和false常量应该被视为预定义的全局变量,而不是直接作为语言的一部分实现。因此,我在创建ScriptInterpreter时将它们定义为全局变量。
应该注意,通过这种方式,它们可以被脚本修改,因为它们不是常量,而是简单的全局变量。可能有更好的方法来做这件事,但现在就这样做:
var interpreter = new Irony.Interpreter.ScriptInterpreter(
new ExpressionEvaluatorGrammar());
interpreter.Globals["true"] = true;
interpreter.Globals["false"] = false;
interpreter.Evaluate(parsedSample);
2 问题
首先,在二进制运算符规则中,<>
运算符应该位于<
和>
运算符之前:
BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**"
| "<>" | "==" | "<=" | ">=" | "<" | ">" | "!="; // added comparison operators
接下来,我创建了一个LanguageRuntime类的自定义实现,它实现了必要的操作符。public class CustomLanguageRuntime : LanguageRuntime
{
public CustomLanguageRuntime(LanguageData data)
: base(data)
{
}
public override void InitOperatorImplementations()
{
base.InitOperatorImplementations();
AddImplementation("<>", typeof(bool), (x, y) => (bool)x != (bool)y);
AddImplementation("!=", typeof(bool), (x, y) => (bool)x != (bool)y);
AddImplementation("==", typeof(bool), (x, y) => (bool)x == (bool)y);
}
}
在ExpressionEvaluatorGrammar中,重写CreateRuntime方法以返回CustomLanguageRuntime:
public override LanguageRuntime CreateRuntime(LanguageData data)
{
return new CustomLanguageRuntime(data);
}