使用表达式 AST

发布于 2024-08-28 09:02:34 字数 340 浏览 10 评论 0原文

使用 AST 时是否有最佳实践? 我有一个已解析的表达式 AST。常量表达式、二进制表达式等 我想用来自 AST 的信息填充 GUI 对话框,但在这里我有点困惑,因为我的代码变得非常混乱。

示例:

expression = "Var1 > 10 AND Var2 < 20"

我想分别填充两个文本框的值 10。 20 来自 AST。 我现在正在做的是一种递归方法,它检查正确的子表达式类型(使用.Net Is-operator)并进行相应的操作,代码真的很“臭”:)

是否有任何设计模式,例如 Visitor 等,这使得这更容易/更具可读性/可维护性?

Is there any best practice when working with ASTs?
I have a parsed expression AST. ConstantExpression, BinaryExpression etc.
I want to populate a GUI-dialog with information from the AST, and it's here where I get kinda confused because my code gets pretty messy.

Example:

expression = "Var1 > 10 AND Var2 < 20"

I want to populate two textboxes with value 10 resp. 20 from the AST.
What I'm doing now is a recursive method that checks for correct child expression-types (with .Net Is-operator) and acts accordingly and the code is really "smelly" :)

Is there any design pattern, like Visitor or such, that makes this somewhat easier/more readable/maintainable ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半边脸i 2024-09-04 09:02:34

使用 AST 的最佳实践是:

  • 获得好的解析器来帮助您根据某种语法描述构建 AST
  • 获得一个好的库来帮助您遍历 AST 来收集/修改 AST

对于认真使用 AST 的工作,最好通过以下方式完成使用旨在生成和操作 AST 的包。通常,此类包包含许多附加支持,例如使用源到源转换的模式匹配和/或 AST 重写。

以下是几个:

此示例展示了如何仅使用 BNF、模式和源到- 来构建和操作 AST。源转换。

Best practices for working with ASTs are:

  • Get good parsers to help you build the ASTs from some kind of grammar description
  • Get a good library to help you walk the AST to collect/modify the AST

For serious work with ASTs, this is best done by using a package designed to generate and manipulate ASTs. Often such packages include a lot of additional support, such as pattern matching and/or AST rewriting using source-to-source transformations.

Here are several:

This example shows how to build and manipulate ASTs using only BNF, patterns, and source-to-source transformations.

揪着可爱 2024-09-04 09:02:34

大多数编译器通过使用

  • 重写
  • Visitor 的

方法来解决此问题。以下是如何将表达式中出现的所有常量值(文字)收集到整数的 List 中。然后,调用代码可以使用该列表中的值填充文本框。

方法重写

最顶层的 AST 类定义了一个抽象方法,该方法在子类中被重写。

class AstNode {
  .. // Some stuff
  public abstract void collectValues(List<Integer> ints);
}

class ConstantExpression : AstNode {
  private int value;
  .. // Some stuff
  public override void collectValues(List<Integer> ints) { ints.Add(value); }
}

 class BinaryExpression : AstNode {
   private AstNode left;
   private AstNode right;
   .. // Some stuff
   public override void collectValues(List<Integer> ints) { 
      left.collectValues(ints); 
      right.collectValues(ints); 
   }
}

class Identifier : AstNode {
  .. // Some stuff
  public override void collectValues(List<Integer> ints) { 
     // do nothing!
  }
}

Visitor

相同的程序,但使用 Visitor 编写。

class Visitor {
   public abstract void visit(ConstantExpression e);
   public abstract void visit(BinaryExpression e);
   public abstract void visit(Identifier e);
}

class AstNode {
  .. // Some stuff
  public abstract void accept(Visitor v);
}

class ConstantExpression : AstNode {
  public int value;
  .. // Some stuff
  public override void accept(Visitor v) { v.visit(this); }
}

 class BinaryExpression : AstNode {
   private AstNode left;
   private AstNode right;
   .. // Some stuff
  public override void accept(Visitor v) { 
     left.accept(v); 
     right.accept(v); 
     v.visit(this); 
  }
}

class Identifier : AstNode {
  .. // Some stuff
  public override void accept(Visitor v) { v.visit(this); }
}


class ValueCollector : Visitor {
  public List<Integer> ints = ...;

   public void visit(ConstantExpression e) { ints.Add(e.value); }
   public void visit(BinaryExpression e) { }
   public void visit(Identifier e) { }
}

Most compilers solve this problem by using either

  • Method overriding
  • Visitor

Here are is how you'd go about collecting all constant value (literals) that appears in your expression into a List of integers. Calling code can then populate textboxes with values from this list.

Method overriding

The top-most AST class defines an abstract method which is overridden at subclasses.

class AstNode {
  .. // Some stuff
  public abstract void collectValues(List<Integer> ints);
}

class ConstantExpression : AstNode {
  private int value;
  .. // Some stuff
  public override void collectValues(List<Integer> ints) { ints.Add(value); }
}

 class BinaryExpression : AstNode {
   private AstNode left;
   private AstNode right;
   .. // Some stuff
   public override void collectValues(List<Integer> ints) { 
      left.collectValues(ints); 
      right.collectValues(ints); 
   }
}

class Identifier : AstNode {
  .. // Some stuff
  public override void collectValues(List<Integer> ints) { 
     // do nothing!
  }
}

Visitor

Same program but written using Visitors.

class Visitor {
   public abstract void visit(ConstantExpression e);
   public abstract void visit(BinaryExpression e);
   public abstract void visit(Identifier e);
}

class AstNode {
  .. // Some stuff
  public abstract void accept(Visitor v);
}

class ConstantExpression : AstNode {
  public int value;
  .. // Some stuff
  public override void accept(Visitor v) { v.visit(this); }
}

 class BinaryExpression : AstNode {
   private AstNode left;
   private AstNode right;
   .. // Some stuff
  public override void accept(Visitor v) { 
     left.accept(v); 
     right.accept(v); 
     v.visit(this); 
  }
}

class Identifier : AstNode {
  .. // Some stuff
  public override void accept(Visitor v) { v.visit(this); }
}


class ValueCollector : Visitor {
  public List<Integer> ints = ...;

   public void visit(ConstantExpression e) { ints.Add(e.value); }
   public void visit(BinaryExpression e) { }
   public void visit(Identifier e) { }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文