4

我是Irony和整个语言实现 shebang 的新手,所以我一直在玩Irony 源附带的ExpressionEvaluator示例,这似乎(几乎)适合我正在处理的项目的需求。

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

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)。如何将truefalse定义为常量?
  2. bool2 = (eval == eval2)行失败并显示以下消息:错误:未为 System.Boolean 和 System.Boolean 类型定义运算符“==”。在(6:15)。

编辑:解决了这两个问题,请参阅下面的答案。

4

1 回答 1

9

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

第一期

据我从这个 Irony 讨论线程中可以理解,真假常量应该被视为预定义的全局变量,而不是直接作为语言的一部分来实现。因此,我在创建ScriptInterpreter时将它们定义为全局变量。

应该知道,通过这种方式,它们可以被脚本修改,因为它们不是常量,而只是全局变量。可能有更好的方法来做到这一点,但现在可以这样做:

var interpreter = new Irony.Interpreter.ScriptInterpreter(
  new ExpressionEvaluatorGrammar());
interpreter.Globals["true"] = true;
interpreter.Globals["false"] = false;
interpreter.Evaluate(parsedSample);

第 2 期

首先,<>运算符应该在二元运算符规则中的<and运算符之前:>

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);
}
于 2011-08-02T12:01:58.543 回答