繁体   English   中英

此C ++解析器如何工作?

[英]How does this C++ parser work?

我目前正在阅读Bjarne Stroustrup撰写的“编程:使用C ++的原理和实践”,并且在理解如何实现这种特定语法方面遇到问题。

这是语法及其规则:

Expression:
    Term
    Expression "+" Term
    Expression "-" Term
Term:
    Primary
    Term "*" Primary
    Term "/" Primary
    Term "%" Primary
Primary:
    Number
    "(" Expression ")"
Number:
    floating-point literal

但是,这是Term的实现方式:

double term()
{
    double left = primary();
    Token t = ts.get();        // get the next token from token stream

    while(true) {
        switch (t.kind) {
        case '*':
            left *= primary();
            t = ts.get();
            break;
        case '/':
        {
            double d = primary();
            if (d == 0) error("divide by zero");
            left /= d;
            t = ts.get();
            break;
        }
        default:
            ts.putback(t);     // put t back into the token stream
            return left;
    }
    }
}

为什么我们在switch语句中调用left *= primary(); 如果令牌等于“ *”,而不是left *= term()

我试图替换left *= primary(); left *= term() (除法是否相同),程序仍然可以正常工作。 但是,我不理解Bjarne想到的设计决策,这就是为什么他以自己的方式实现功能。 也许我在这里缺少什么?

提前致谢!

为什么我们在switch语句中调用left *= primary(); 如果令牌等于"*" ,而不是left *= term()?

因为语法说:

Term:
    Primary
    Term "*" Primary
    Term "/" Primary
    Term "%" Primary

请注意,如果C ++(和C)具有幂运算符,或者他的示例语法具有一元运算符,那么您将看到的是更常见的:

Expression:
    Term
    Expression "+" Term
    Expression "-" Term
Term:
    Factor
    Term "*" Factor
    Term "/" Factor
    Term "%" Factor
Factor:
    Primary
    Primary "**" Factor /* note right-associativity */
Primary:
    "+" Primary
    "-" Primary
    Number
    "(" Expression ")"
Number:
    floating-point literal

因为生产不是Term "*" Term

这是Term "*" Primary

在语法本身中这样做的原因是,如果您在表达式中有任何嵌套的Term ,则从解析的角度来看,它们被迫“出现”在左侧。 有效地说服了右侧仅包含主表达式(不包含其他运算符)。 当将此方法应用于递归解析“程序”时,结果是运算符是左关联的,结果是((a*b)*c) ,而不是(a*(b*c))

这样的语法只会“向下”传播,而不会“向上”传播,否则您将陷入一团糟的歧义,或者至少会出现一种不自然的联想,从而使试图用您的语言编写算术的人们感到困惑。

当然,对于乘法,算术结果在理论上是相同的。 但是,当您开始使用其他运算符时,问题变得很明显: ((a*b)/c)(a/(b*c))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM