递归下降方法和LL(1)实现计算器C++

编译原理书上的,原理还搞得不太清楚,不过代码应该符合书上的原理吧!把代码贴出来:

  递归下降:

/*
递归下降的整型算术
EBNF:
     <exp> => <term> {<addop> <term>} 
     <addop> => +|-
     <term> => <factor> {<mulop> <factor>}
     <mulop> => * | \
     <factor> (<exp>) | Number
*/

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
char token;
double exp(void);
double term(void);
double factor(void);
void error(){
     //printf("Error");
     fprintf(stderr,"Error\n");
     
     exit(1);
}
void match(char expectedToken){
     if(token == expectedToken) token = getchar();
     else error();
}
int main()
{
    double result;
    int n;
    scanf("%d",&n);
    getchar();
    while(n--){
    token = getchar();
    result = exp();
    if(token == '='){
         getchar();
         printf("%.2lf\n",result);
       //printf("Result = %.2lf\n",result);
       }
    else error();
   }
   // system("pause");
    
    return 0;
}
double exp(){
    double temp = term();
    while(token == '+' || token == '-')
    {
                switch(token){
                   case '+':match('+');
                            temp += term();
                            break;
                   case '-':match('-');
                            temp -=term();
                            break;
                }
    }
    return temp;
}
double term(){
    double temp = factor();
    while(token == '*' || token == '/')
    {
       switch(token){
         case '*':match('*');
                  temp *= factor();
                  break;
         case '/':match('/');
                  temp /= factor();
                  break;
         }
    }
    return temp;
}
double factor(){
    double temp;
       if(isdigit(token)){
         ungetc(token,stdin);
         scanf("%lf",&temp);
         token = getchar();
         
       }
       else if(token == '('){
            match('(');
            temp = exp();
            match(')');
       }
       else error();
    return temp;
}
       


LL(1)方法:LL(1)表来自书上p121-p122

#include<iostream>
#include<cstdio>
#include<string>
#include<stack>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAX 10
string M[MAX][MAX];
stack<char> Q;
stack<double> ans;
char termi[8] = {'(','1',')','+','-','*','/','$'}; //判断列是否是终结符 
char next;
void init()
{
     for(int i = 0;i < MAX;i++)
       for(int j = 0;j < MAX;j++)
           M[i][j] = "-1";
           
     M[0][0] = "31",     M[0][1] = "31";
     M[1][3] = "23+1",   M[1][4] = "23-1";
     M[2][3] = "+",      M[2][4] = "-";
     M[3][0] = "64",     M[3][1] = "64";
     M[4][5] = "56*4",   M[4][6] = "56/4";
     M[5][5] = "*",      M[5][6] = "/";
     M[6][0] = "(0)",    M[6][1] = "#"; //#表示是number 
     
     
}
int isTermi(char x)
{
    for(int i = 0;i < 8;i++)
        if(x == termi[i])
           return i;  //这是一个终结符
    if(isdigit(x)) return 1;
    
    return -1;//不是终结符 
    
}
int match(char x,char y)  //x is top
{
    if(x == '#' && isdigit(y)) return 1;
    else if(x == y) return 1;
    return 0;
}
double solve()
{
    int x = 0;
    int y = 0;
    string str;
    Q.push('$');
    Q.push('0');
    next = getchar();
   
    while(Q.top() != '$' || next != '$')
    {
       // printf("stack top = %c next = %c\n",Q.top(),next);
         if(!isdigit(Q.top()))  //Q.top()是终结符 
                 {
                     if(match(Q.top(),next))
                       {
                           if(isdigit(next)) //计算值 
                            {                           
                               //ans.push(next);
                               ungetc(next,stdin);
                               double num ;
                               scanf("%lf",&num);
                               ans.push(num);
                               
                            }
                           Q.pop();next = getchar();
                       } //if......成立 
                   else  //如果next != Q.top() 
                    {                
                           char type = Q.top();
                           Q.pop();
                           double a = ans.top();ans.pop();
                           double b = ans.top();ans.pop();
                           double re;
                           if(type == '+') {re = b + a;}
                           else if(type == '-') {re = b - a;}
                           else if(type == '*') {re = b * a;}
                           else if(type == '/') {re = b / a;}
                           else ;
                           ans.push(re);
                          
                          
                    }   
                }   
                
                    
        else if (isdigit(Q.top()) && (y =isTermi(next)) >= 0)  //top非终结符,next终结符 
           {
                x = Q.top() - '0';
                //printf("x = %d y = %d\n",x,y);
                str = M[x][y];
                Q.pop();
                if(str != "-1")
                for(int k = str.length() - 1;k >= 0;k--)
                     Q.push(str[k]);
                
           } 
        else printf("error\n");
   }  //end while
    //Q.pop();ans.pop();
    //printf("ggggggggg%c\n",next);
    return ans.top();
}
      
/*typedef enum 
{  EXP,EXP1,ADDOP,TERM,TERM1,MULOP,FACTOR}
   Mtype;
  */ 
int main()
{
      /****************************/
    #ifndef ONLINE_JUDGE
    freopen("F:\\School\\C&C++\\C\\in.txt","r",stdin);
    freopen("F:\\School\\C&C++\\C\\out.txt","w",stdout);
    #endif
    /****************************/
     init();
     //printf("init over");
     int time;
     scanf("%d",&time);
     getchar();
     while(time--)
     {
         if(next == '$')
            getchar();  //吸收'\n' 
      double c = solve();
       printf("ans = %lf\n",c);
       Q.pop();ans.pop();
     }

    /****************************/
    #ifndef ONLIINE_JUDGE
    fclose(stdin);
    fclose(stdout);
    #endif
    /****************************/
    system("pause");
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值