0 Star 0 Fork 70

王小涛/compiler-homework3

forked from zren/compiler-homework3 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
calculator.c 3.30 KB
一键复制 编辑 原始数据 按行查看 历史
wangxiaotao 提交于 2016-05-06 11:04 . update1
#include <stdio.h>
#include <ctype.h>
//#include<iostream>
#include<math.h>
//using namespace std;
//E -> TE'
//E' -> +TE' | e
//T -> FT'
//T' -> *FT' | e
//F -> NUM | (E)
//FIRST(E) = {NUM, LEFTB}
//FIRST(E') = {PLUS, e}
//FIRST(T) = {NUM, LEFTB}
//FIRST(T') = {MULT, e}
//FIRST(F) = {NUM, LEFTB}
//FOLLOW(E) = {$, RIGHTB}
//FOLLOW(E') = {$, RIGHTB}
//FOLLOW(T) = {PLUS, RIGHTB, $}
//FOLLOW(T') = {PLUS, RIGHTB, $}
//FOLLOW(F) = {MULT, PLUS, RIGHTB, $}
enum TOKEN {PLUS, MULT, NUM, END, ERR, LEFTB, RIGHTB};
char lookahead;
enum TOKEN token;
int num;
int error = 0;
FILE *fp;
void lexical(FILE *fp);
int match(enum TOKEN x);
int E();
int E_();
int T();
int T_();
int F();
//return 0 if success, return 1 otherwise
int match(enum TOKEN x) {
if(token == x) {
lexical(fp);
return 0;
} else {
error = 1;
return 1;
}
}
//E -> TE'
int E() {
switch (token)
{
case LEFTB: case NUM:
return T() + E_();//一旦匹配到E_()就得 加上所匹配的东西
default:
error = 1;//报错
printf("error E()");
break;
}
return 0;
}
//E_ -> +TE'|e
int E_() {
switch (token)
{
case PLUS:
match(PLUS); return T() + E_();//由于T()后面是E_()所以加上自身
case RIGHTB: case END:
return 0;//加上0 和不变
default:
error = 1;//报错
printf("error E_()");
break;
}
return 0;
}
//T -> FT'
int T() {
switch (token)
{
case LEFTB: case NUM:
return F()*T_();
default:
error = 1;//报错
printf ("error T()");
break;
}
return 0;
}
//T' -> *FT' | e
int T_() {
switch (token)
{
case MULT:
match(MULT); return F()*T_();
case PLUS: case RIGHTB: case END:
return 1;
default:
error = 1;//报错
printf( "error T_()") ;
break;
}
return 0;
}
//F -> NUM | (E)
int F() {
double temp;//用于保存E()的值
switch (token)
{
case LEFTB:
match(LEFTB);
temp = E();
match(RIGHTB);
return temp;
case NUM:
temp = num;
match(NUM);
return temp;
default:
error = 1;//报错
printf("error F()");
break;
}
return 0;
}
//读入文本,保存记号流,将记号保存在 token 中,数字 保存在NUM 中
void lexical(FILE *fp) {
lookahead = getc(fp);
num = 0;
while (lookahead == ' ' || lookahead == '\t' || lookahead == '\n') {
lookahead = getc(fp);
}
if (isdigit(lookahead)) {
int count = 0;
if (isdigit(lookahead) || lookahead == '.'){
num = 0;
while (isdigit(lookahead)) {
token = NUM;
num = num * 10 + lookahead - '0';//相当于左移一位
lookahead = getc(fp);
}
if (lookahead == '.'){
lookahead = getc(fp);
while (isdigit(lookahead)){
num = num * 10 + lookahead - '0';//相当于左移一位
lookahead = getc(fp);
count++;
}
num = (num * (pow(0.1,count)));//移动小数点
}
ungetc(lookahead, fp);//回退一步
return;
}
}
else if (lookahead == '+') {
token = PLUS;
return;
}
else if (lookahead == '*') {
token = MULT;
return;
}
else if (lookahead == EOF) {
token = END;
return;
}
else if (lookahead == '(') {
token = LEFTB;//左括号
return;
}
else if (lookahead == ')') {
token = RIGHTB;//右括号
return;
}
else {
error = 1;//有错误
token = ERR;
return;
}
}
//F -> NUM | (E)
int main(int argc, char **argv) {
int res = 0;
if(argc < 2) {
printf("insufficient arguments");
return 1;
}
fp = fopen(argv[1], "r");
lexical(fp);
res = E();
if(!error) {
printf("%d\n", res);
} else {
printf("There are errors\n");
}
fclose(fp);
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/wangxiaotao/compiler-homework3.git
git@gitee.com:wangxiaotao/compiler-homework3.git
wangxiaotao
compiler-homework3
compiler-homework3
master

搜索帮助