解析完全括号表达式

时间:2012-12-15 13:41:12

标签: c++ parsing recursive-descent

我正在尝试为这个语法解析一个完全带括号的Exp:

exp->(exp + exp)
    |(exp - exp)
    | num
num->[0-9]

...但我有一个问题:当我输入“1 + 4”时,不会出现错误。我怎么解决呢?

2 个答案:

答案 0 :(得分:2)

这是递归下降解析器的经典问题:您的语法不需要消耗整个输入。一旦完成“while isdigit”循环,它就会考虑完成工作,忽略输入的+4部分。

在调用顶级表达式后添加检查是否到达行尾以解决此问题:

void TopExp() {
    Expr();
    Match('\n');
}

当没有其他输入可用时,您需要修改Match以允许匹配\n

void Match(char c) {
    int p = cin.peek();
    if(p==c) {
        cin>>c;
    } else if (p == EOF && c == '\n') {
        return
    } else {
        cout<<"Syntax Error! "<<(char)cin.peek()<<endl;
        cin.ignore();
    }
}

答案 1 :(得分:2)

尝试使用此更改的指令:if(openParenthesis-closeParenthesis&gt; 0)

    int Match(char c)
    {
        if(cin.peek()==c) {
            cin>>c;
            return 1;
        } else
        {
            cout<<"Syntax Error! "<<(char)cin.peek()<<endl;
            cin.ignore();
            return 0;
        }
    }

    void MatchOp()
    {
        if(cin.peek()=='+') 
            Match('+');
        else if(cin.peek()=='-')
            Match('-');
        else
        {
            cout<<"invalid Operation: "<<(char)cin.peek()<<endl;
            cin.ignore();
        }
    }

    void Exp()
    {   static int openParenthesis = 0; 
        static int closeParenthesis = 0;  
        if(cin.peek()!='\n')
            if(cin.peek()=='(')
            {
                if (Match('(') == 1) {
                    openParenthesis += 1;
                }
                Exp();MatchOp();Exp();
                if (Match(')') == 1) {
                    closeParenthesis -= 1;
                }
            }
            else if(isdigit(cin.peek()))
            {   
                if (openParenthesis-closeParenthesis>0) {
                    cout<<"Syntax Error! "<<(char)cin.peek()<<endl;
                    cin.ignore();               
                } else {
                    while(isdigit(cin.peek()))
                    { cout<<(char)cin.peek();
                    Match(cin.peek());  
                    }
                }   
            }
            else 
            {
                cout<<"Syntax Error!"<<(char)cin.peek()<<endl;
                cin.ignore();
            }
    }