C++ Bjarne Stroustrup编程实践与原则第7章

C++ Bjarne Stroustrup编程实践与原则第7章,c++,C++,我有一个关于逻辑流的问题: I'm trying to create a calculator functionality that: 1.lets you assign a declare a variable (eg, let x = 5;) 2. that will also let you reassign a value (eg, x = 10;) 3. will let you use values in expressions (eg, x + 5; returns 15)

我有一个关于逻辑流的问题:

I'm trying to create a calculator functionality that: 
1.lets you assign a declare a variable (eg, let x = 5;) 
2. that will also let you reassign a value (eg, x = 10;)
3. will let you use values in expressions (eg, x + 5; returns 15)
底部的函数语句()应该决定令牌\u stream::get()是否 返回声明、重新分配或表达式,然后运行相应的代码

使其能够使Token_stream::get()返回语句()的名称 并要求重新分配。我的功能丢失到了 让表达式()以名称开头。如果我写信

x+5

它将从赋值中抛出一个错误,因为它读取x并查找= 而不是调用表达式

如果token token_stream::get()读取一个后跟“=”的字符串,然后将该名称放回输入流中,这样我就可以为赋值获取if,那么我想为赋值创建一个特殊的token以在语句()中使用。有什么建议吗

    //------------------------------------------------------------------------------
        Token Token_stream::get()
        {
            if (full) { full=false; return buffer; }
            char ch;
            cin >> ch;
            switch (ch) {
            case '(':
            case ')':
            case '+':
            case '-':
            case '*':
            case '/':
            case '%':
            case ';':
            case '=':
            case ',': 
                return Token(ch);
            case '.':
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            {   cin.unget();
                double val;
                cin >> val;
                return Token(number,val);
            }
            default:
                if (isalpha(ch)) {
                    string s;
                    s += ch;
                      while(cin.get(ch) && (isalpha(ch) || isdigit(ch))||        ch    =='_' )   s+=ch;
                    cin.unget();
                    if (s ==   "let")   return Token(let);
                    if (s == "const")   return Token(constant);   
                    if (s ==     "q")   return Token(quit);
                    if (s ==  "sqrt")   return Token(square_root); 
                    if (s ==   "pow")   return Token(exponent);       
                    return Token(name,s);
                }
                error("Bad token");
            }
        }
        //------------------------------------------------------------------------------
        //------------------------------------------------------------------------------------------------
        double statement()
        {
            Token t = ts.get();
            switch(t.kind) 
                {
                case let: 
                    return declaration();

                case name:
                    ts.unget(t);
                    return assigment();

                case constant: 
                    return declare_constant();

                default:
                    ts.unget(t);
                    return expression();
                }
        }
        //----

我不会将错误处理逻辑放在标记器类中——它应该是一个相当愚蠢的文本muncher,只在空白处拆分它并将标记返回给调用方

假设您开始解析一条语句,您的标记化程序返回
let
。现在你知道了,接下来应该是一个声明。下一个标记应该是尚未存在的变量的唯一名称。因此,您再次调用
Token\u stream::get()
,看看您得到了什么。成功后,您将获得下一个令牌,并查看是否获得
=
。等等


类似地,您将获得一个变量的名称作为语句的第一个标记。检查是否已声明,如果尚未声明,则报告错误。你检查另一个令牌。它应该是某种类型的运算符(可能包括
=
)。如果你得到了它,你就开始寻找一个有效的术语(一个值,另一个变量,一个表达式…)。等等。

我不会将错误处理逻辑放在标记器类中-它应该是一个相当愚蠢的文本框,只在空白处拆分它并将标记返回给调用方

假设您开始解析一条语句,您的标记化程序返回
let
。现在你知道了,接下来应该是一个声明。下一个标记应该是尚未存在的变量的唯一名称。因此,您再次调用
Token\u stream::get()
,看看您得到了什么。成功后,您将获得下一个令牌,并查看是否获得
=
。等等

类似地,您将获得一个变量的名称作为语句的第一个标记。检查是否已声明,如果尚未声明,则报告错误。你检查另一个令牌。它应该是某种类型的运算符(可能包括
=
)。如果你得到了它,你就开始寻找一个有效的术语(一个值,另一个变量,一个表达式…)。等等