从Token Stream解析表达式

时间:2014-12-12 18:39:27

标签: parsing expression

我试图解析一个简单的脚本语言的表达式,但我很困惑。现在,只能将数字和字符串文字解析为表达式:

int x = 5;
double y = 3.4;
str t = "this is a string";

但是,我对解析更复杂的表达式很困惑:

int a = 5 + 9;
int x = (5 + a) - (a ^ 2);

我想我会像以下那样实现它:

do {
    // no clue what I would do here?        

    if (current token is a semi colon) break;
}
while (true);

任何帮助都会很棒,我不知道从哪里开始。感谢。

编辑: 我的解析器是递归下降解析器

我的表达"班级"如下:

typedef struct s_Expression {
    char type;
    Token *value;

    struct s_Expression *leftHand;
    char operand;
    struct s_Expression *rightHand;
} ExpressionNode;

有人提到递归下降解析器能够解析表达而不做中缀,而不是postfix。最好是,我想要一个像这样的表达式:

例如:

int x = (5 + 5) - (a / b);

将被解析为: 注意:这不是有效的C,这只是一些伪的代码来简单地说明我的观点:)

ExpressionNode lh;
lh.leftHand = new ExpressionNode(5);
lh.operand = '+'
lh.rightHand = new ExpressionNode(5);

ExpressionNode rh;
rh.leftHand = new ExpressionNode(a);
rh.operand = '/';
rh.rightHand = new ExpressionNode(b);

ExpressionNode res;
res.leftHand = lh;
res.operand = '-';
res.rightHand = rh;

我很晚才问这个问题,很抱歉,如果我不清楚,我完全忘记了我最初的目标。

3 个答案:

答案 0 :(得分:1)

有多种方法可以做到这一点。我过去使用的是读取输入字符串(即编程语言代码)并将表达式从中缀转换为反向抛光表示法。这是一篇关于这样做的非常好的帖子:

http://andreinc.net/2010/10/05/converting-infix-to-rpn-shunting-yard-algorithm/

请注意,=也是一个运算符,因此您的解析应该包含整个代码文件,而不仅仅是某些表达式。

一旦进行反向抛光,表达式就非常容易评估。您只需弹出堆栈,随时存储操作数,直到您遇到操作员。根据操作员的要求从堆栈中弹出尽可能多的操作数并执行操作。

答案 1 :(得分:1)

我最终使用的方法是Operator precedence parsing

parse_expression_1 (lhs, min_precedence)
    lookahead := peek next token
    while lookahead is a binary operator whose precedence is >= min_precedence
        op := lookahead
        advance to next token
        rhs := parse_primary ()
        lookahead := peek next token
        while lookahead is a binary operator whose precedence is greater
                 than op's, or a right-associative operator
                 whose precedence is equal to op's
            rhs := parse_expression_1 (rhs, lookahead's precedence)
            lookahead := peek next token
        lhs := the result of applying op with operands lhs and rhs
    return lhs

答案 2 :(得分:0)

如果你正在构建一个递归下降解析器,实现一个分流码是很多不必要的工作,因为递归下降完全能够自己评估表达式或输出RPN。

您还没有告诉我们您的编程语言,Token结构,甚至是您想要实现的内容,因此很难为您提供示例代码。看看Eric White在C#中递归下降解析器的implementation。如果您提供更多详细信息,我们将提供更多帮助。