1

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

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)

底部函数 statement() 应该决定 Token Token_stream::get() 是否返回声明、重新分配或表达式,然后运行适当的代码。

使 Token_stream::get() 返回名称到 statement() 并调用重新分配。我失去了以名称开头的表达式()的功能。例如。如果我写

x + 5;

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

如果 Token Token_stream::get() 读取一个字符串后跟一个“=”,我想创建特殊的分配令牌以在 statement() 中使用,但是然后将名称放回输入流中,以便我可以获取分配的 if . 有什么建议吗?

    //------------------------------------------------------------------------------
        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();
                }
        }
        //----
4

1 回答 1

1

我不会将错误处理逻辑放在标记器类中 - 它应该是一个非常愚蠢的文本咀嚼器,只是将其拆分为空格并将标记返回给调用者。

因此,假设您开始解析语句并且您的 tokeninizer 返回let。现在你知道接下来应该是一个声明。下一个标记应该是一个尚不存在的变量的唯一名称。所以你Token_stream::get()再次打电话,看看你得到了什么。成功后,您将获得下一个令牌并查看是否获得=. 等等。

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

于 2013-10-21T17:41:58.413 回答