使用递归

时间:2017-03-08 14:56:55

标签: c++ compiler-construction parse-tree

我正在努力寻找中缀到前缀翻译方案。

我认为中缀是postfix translation sceme:

expr -> Term, Rest
Rest -> +Term, { print('+') } , Rest | -Term, { print('-') }, Rest | epsilon
Term -> Factor, Rest_
Rest_ -> *Factor, { print('*') }, Rest_ | /Factor, { print('/') }, Rest_ | epsilon
Factor -> Digit | (expr)
Digit -> 0,1,2,3,4,5,6,7,8,9

根据上述翻译方案我的中缀到后缀转换代码:

#include<iostream>

using namespace std;

const char input[] = "9-5*2";
int index = 0;
char LookAhead = input[index];

void Match(char newChar);
void Factor();
void Rest_();
void Rest();
void Term();
void Expression();


int main(){
    Expression();
    return 0;
}

void Match(char newChar){
    if(newChar == LookAhead){
        index++;
        LookAhead = input[index];
    }
}

void Expression(){
    Term();
    Rest();
}

void Term(){
    Factor();
    Rest_();
}

void Rest(){
    if(LookAhead == '+'){
        Match('+');
        Term();
        cout << '+';
        Rest();
    }else if(LookAhead == '-'){
        Match('-');
        Term();
        cout << '-';
        Rest();
    }else{

    }
}

void Rest_(){
    if(LookAhead == '*'){
        Match('*');
        Factor();
        cout << '*';
        Rest_();
    }else if(LookAhead == '/'){
        Match('/');
        Factor();
        cout << '/';
        Rest_();
    }else{

    }
}

void Factor(){
    if(isdigit(LookAhead)){
        cout << LookAhead;
        Match(LookAhead);
    }
}

所以现在有任何专家可以帮我理解中缀转换翻译方案,我们将不胜感激。

我们可以通过解析树进行测试。如果我们可以从示例字符串 9-5 + 2 生成类似 -9 + 52 前缀字符串的内容。

告诉我是否需要更多地了解我的中缀到postfix转换方案和代码以便更好地理解。

提前致谢!

已编辑: 我只是在查找中缀到前缀表达式转换翻译方案时遇到问题。举个例子, 我的意见:

9-5+2

预期产出:

-9+52

我希望用上面显示的与中缀到后缀转换相同的结构来实现这一点。 这就是全部!

2 个答案:

答案 0 :(得分:1)

最简单的解决方案是在解析时构造Abstract Syntax Tree (AST),然后使用preorder traverse递归遍历树。

你也可以随时构建字符串(例如建议的here by @ChrisDodd),但是:

  • 这不是递归解决方案:)和
  • 它涉及大量字符串复制,因此它可能具有二次运行时间。

将后缀转换为某种临时数据结构(例如堆栈)似乎很有诱惑力,然后通过打印前缀表达式递归地遍历后缀表示“evaluate”。这肯定会有效,但是你会遇到这样的问题:以自然的方式遍历postfix表示将首先访问每个表达式的右手参数,而你首先想要的是左手参数。这意味着您需要向后构造字符串,这涉及另一个临时数据结构(例如,另一个堆栈)。

总体而言,AST解决方案更加清晰,为将来添加更多功能提供了良好的基础。

答案 1 :(得分:0)

所以我使用了一个时间变量来存储我的数字,并通过维护订单的优先级来递归地检查和打印运算符。

我的解决方案:

#include<iostream>

using namespace std;

const char input[] = "9-5+2";
int index = 0;
char LookAhead = input[index];
char TempLookAhead = 'x';

void Match(char newChar);
void Factor();
void Rest_();
void Rest();
void Term();
void Expression();


int main(){
    Expression();
    return 0;
}

void Match(char newChar){
    if(newChar == LookAhead){
        index++;
        LookAhead = input[index];
    }
}

void Expression(){
    Term();
    Rest();
    cout << TempLookAhead;
}

void Term(){
    Factor();
    Rest_();
}

void Rest(){
    if(LookAhead == '+'){
        cout << '+';
        cout << TempLookAhead;
        Match(LookAhead);
        Term();
        Rest();
    }else if(LookAhead == '-'){
        cout << '-';
        cout << TempLookAhead;
        Match(LookAhead);
        Term();
        Rest();
    }else{

    }
}

void Rest_(){
    if(LookAhead == '*'){
        cout << '*';
        cout << TempLookAhead;
        Match(LookAhead);
        Factor();
        Rest_();
    }else if(LookAhead == '/'){
        cout << '/';
        cout << TempLookAhead;
        Match(LookAhead);
        Factor();
        Rest_();
    }else{

    }
}

void Factor(){
    if(isdigit(LookAhead)){
        TempLookAhead = LookAhead;
        Match(LookAhead);
    }
}