编译原理书上的,原理还搞得不太清楚,不过代码应该符合书上的原理吧!把代码贴出来:
递归下降:
/*
递归下降的整型算术
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;
}