编译原理之后缀表达式生成与计算

编译原理之后缀表达式生成与计算

文法参照上一篇编译原理之消除算术表达式文法的左递归

将算数表达式解析为后缀表达式是不少脚本语言的运行时的计算方案。

根据原文法:

expr -> expr + term     
      | expr - term     
      | term            

term -> term * factor   
      | term / factor   
      | factor          

factor -> ( expr )      
        | number        
        | id

我们先罗列出要实现的函数:

class Parser {
public:
    void expr(LexerStream* lexers)
    {
    }

    void term(LexerStream* lexers)
    {
    }

    void factor(LexerStream* lexers)
    {
    }
};

其中的 LexerStream 为词素序列流。

再根据消除左递归的文法实现递归算法:

expr     -> term trest

trest    -> + term
          | - term
          | ε

term     -> factor frest

frest    -> * factor
          | / factor
          | ε

factor   -> NUMBER
          | ( expr )

先看未消除左递归的 expr 产生式和消除左递归 exprtrest 的产生式。原 expr 产生式本身是左递归的,所以在递归下降算法中是对应到一个内部循环。

所以先给出 expr 的实现:

void expr(LexerStream* lexers)
{
    term(lexers);
    while(lexers->current() == "+" || lexers->current() == "-") {

        string op = lexers->current();

        lexers->next();
        term(lexers);

        cout << op;     // PUSH
    }
}

其他产生式类似:

void term(LexerStream* lexers)
{
    factor(lexers);

    while(lexers->current() == "*" || lexers->current() == "/") {

        string op = lexers->current();

        lexers->next();
        factor(lexers);

        cout << op;     // PUSH
    }
}

void factor(LexerStream* lexers)
{
    string current = lexers->current();

    if(current == "(") {
        lexers->next();

        expr(lexers);
        lexers->next();

        string e = lexers->current();
        if(e != ")") {
            cout << "lost `(" << endl;
        }
    } else {
        cout << current;      // PUSH

        lexers->next();
    }
}

详细代码前往 LearnCompilers/HLL/calculator001 下载。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值