我有两个关于如何编写递归下降解析器的问题:
第一个是什么时候你有一个非终结者可以匹配几个不同的非终结者之一?你如何检查哪种方式是正确的?
其次,你如何构建AST?使用YACC,我可以编写一段代码来执行非终结符的每个实例,并且它具有引用规则“值”的特殊变量。你如何在递归下降解析器中做类似的事情?
答案 0 :(得分:5)
如,
class ASTNode {
public:
virtual int eval() = 0;
virtual ~ASTNode() = 0;
};
// construct this when parsing an integer literal
class Value : ASTNode {
int v;
public:
Value(int v_) : v(v_) {}
virtual int eval() { return v; }
virtual ~Value() {}
};
// construct this when parsing "x+y"
class Addition : ASTNode {
ASTNode *left, *right;
public:
Addition(ASTNode *l, ASTNode *r) : left(l), right(r) {}
virtual int eval() { return l->eval() + r->eval(); }
virtual ~Addition() { delete left; delete right; }
};
答案 1 :(得分:0)
第一个是什么时候你有一个非终结者可以匹配几个不同的非终结者之一?你如何检查哪种方式是正确的?
您需要在流中展望并做出决定。很难在RDC上进行回溯。
更简单的解决方案是设计语法,使其不需要向前看(硬)。
其次,你如何建立一个AST?
函数调用的返回值是调用解析的所有内容的树。将所有子调用包装到另一个动态分配的对象中并返回该对象。