编写代码以生成解析树

时间:2012-02-14 10:21:18

标签: algorithm

在一个采访问题中我问过这个问题:

编写一个代码来生成解析树,就像编译器在内部为任何给定的表达式做的那样。例如:

a+(b+c*(e/f)+d)*g 

4 个答案:

答案 0 :(得分:3)

简单的方法是将表达式转换为后缀表示法(abcef / * ++)&然后参考这个问题的答案(http://stackoverflow.com/questions/423898/postfix-notation-to-expression-tree)将后缀表达式转换为树。

这是面试官所期望的:)

答案 1 :(得分:3)

首先定义语言。没有人可以将解析器或编译器实现到没有很好定义的语言。举个例子:'a +(b + c *(e / f)+ d)* g',它应触发以下问题:

  1. 语言是单个表达式,还是可能有多个语句(以';'分隔?
  2. 什么是'a','b',...'g'代币?它变化了吗?变量的语法是什么?它是一个类似C的变量,还是一个单独的字母数字字符,如你的例子所暗示的那样。
  3. 您的示例中有3个二进制表达式。这就是全部?语言是否也支持' - '。您的语言是否支持逻辑和按位运算符?
  4. 语言是否支持数字文字?只有整数?双?语言是否支持字符串文字?你引用字符串文字吗?
  5. 评论语法?
  6. 哪个运营商优先? “*”运算符是否优先于示例中的“+”?操作数是从右到左,从左到右进行评估的?
  7. 任何预处理?
  8. 一旦你掌握了语言语法的良好定义,就要开始实现一个标记器。标记化器获取字符流并生成标记列表。在上面的示例中,每个字符都是一个标记,但在var * 12(var power 12)中有3个标记:'var',' *'和'12'。如果允许使用正则表达式,则可以使用正则表达式执行此部分解析。

    接下来,有一个按类型标识每个标记的函数:它是一个运算符,它是一个变量,一个数字文字,字符串文字等。在一个名为NextToken的方法中打包所有,它返回一个标记及其类型。 / p>

    最后,开始解析。在上面的示例中,解析树的根将是一个带有“+”运算符的节点(优先于'')。左子项是变量标记'a',右子项是具有根元素''标记的树。递归地工作。

答案 2 :(得分:1)

每当您打算编写解析器时,要问的主要问题是您是要手动执行还是使用解析器生成器框架。

在这种情况下,我会说自己写一遍是一个很好的练习。

从树本身的良好表示开始。这将是您算法的输出。例如,这可以是对象的集合,其中一个对象类可以表示示例中的abc之类的“标签”。其他人可能代表数字。然后,您可以定义运算符的表示,例如+是一个二元运算符,它有两个子对象,表示左右子表达式。

下一步是实际的解析器,我建议一个经典的递归式解析器。描述这一点并提供标准伪代码实现的一个文本是Theodore Norvell

的文本

答案 3 :(得分:0)

我从简单的语法开始,类似于ANTLR和JavaCC使用的语法。