在Irony中定义常量和运算符

时间:2011-08-02 10:32:10

标签: c# boolean-expression expression-evaluation irony

我是Irony的新手和整个语言实现shebang,所以我一直在玩ExpressionEvaluator附带的Irony source样本,这似乎(几乎)适合我正在进行的项目的需要。

但是,我希望它也支持布尔值,所以我将比较运算符添加到二元运算符列表中,如下:

BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "**"
  | "==" | "<=" | ">=" | "<" | ">" | "!=" | "<>"; // added comparison operators

以下是我想要实现的一个例子:

x = 1
y = 2
eval = x < 2
eval2 = y < x
bool = true
bool2 = (eval == eval2)

由于添加了二元运算符,它成功解析了上述内容。但是,在编译和运行代码时,它在最后两行失败。

  1. bool = true行失败并显示以下消息:错误:变量true未定义。在(5:8)。如何将 true false 定义为常量?
  2. bool2 = (eval == eval2)行失败,并显示以下消息:错误:未对类型System.Boolean和System.Boolean定义运算符'=='。在(6:15)。
  3. 修改:解决了这两个问题,请参阅下面的答案。

1 个答案:

答案 0 :(得分:9)

好的,解决了这两个问题。希望这对其他人有帮助。

第1期

据我所知this Irony discussion thread 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);
}