ber*_*hof 4 c# irony boolean-expression expression-evaluation
我是Irony和整个语言实现shebang的新手,所以我一直在玩Irony源附带的ExpressionEvaluator示例,这似乎(几乎)适合我正在进行的项目的需求.
但是,我希望它也支持布尔值,所以我将比较运算符添加到二元运算符列表中,如下所示:
BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**"
| "==" | "<=" | ">=" | "<" | ">" | "!=" | "<>"; // added comparison operators
Run Code Online (Sandbox Code Playgroud)
这是我想要实现的一个例子:
x = 1
y = 2
eval = x < 2
eval2 = y < x
bool = true
bool2 = (eval == eval2)
Run Code Online (Sandbox Code Playgroud)
由于添加了二元运算符,它成功解析了上述内容.但是,在编译和运行代码时,它在最后两行失败.
bool = true行失败并显示以下消息:错误:变量true未定义.在(5:8).如何将true和false定义为常量?bool2 = (eval == eval2)行失败并显示以下消息:错误:未为类型System.Boolean和System.Boolean定义Operator'=='.在(6:15). 编辑:解决了这两个问题,请参阅下面的答案.
好的,解决了这两个问题.希望这可以对其他人有所帮助.
至于我可以理解这种反讽的讨论话题,真和假常量应被视为预定义的全局变量,而不是直接实现为语言的一部分.因此,我在创建ScriptInterpreter时将它们定义为全局变量.
应该意识到,通过这种方式,它们可以被脚本修改,因为它们不是常量,而只是全局变量.可能有更好的方法来做到这一点,但现在这样做:
var interpreter = new Irony.Interpreter.ScriptInterpreter(
new ExpressionEvaluatorGrammar());
interpreter.Globals["true"] = true;
interpreter.Globals["false"] = false;
interpreter.Evaluate(parsedSample);
Run Code Online (Sandbox Code Playgroud)
首先,<>运算符应该在二元运算符规则中的<and >运算符之前:
BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**"
| "<>" | "==" | "<=" | ">=" | "<" | ">" | "!="; // added comparison operators
Run Code Online (Sandbox Code Playgroud)
接下来,我创建了一个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);
}
}
Run Code Online (Sandbox Code Playgroud)
在ExpressionEvaluatorGrammar,覆盖CreateRuntime方法返回的实例CustomLanguageRuntime:
public override LanguageRuntime CreateRuntime(LanguageData data)
{
return new CustomLanguageRuntime(data);
}
Run Code Online (Sandbox Code Playgroud)