#include <stdio.h> #include <vector> #include <algorithm> #include <functional> #include <string> #include <map> #include <iostream> using namespace std; #define ID 1 #define ERROR 255 enum TYPE{ INT=1, FLOAT, CHAR, }; struct Value{ TYPE type; union { int v1; double v2; char *v3; }; template<typename T> void setValue(T v){ if(type == FLOAT){ v2 =v; } else if(type==INT){ v1=v; } } template<typename T> T getValue(T x){ if(type == FLOAT){ return v2; } else if(type==INT){ return v1; } } }; struct Expression{ enum{ NUM_INT =2, NUM_FLOAT , PLUS , MINUS // ‘-‘ , TIMERS // ‘*’ , OVER // ‘/’ , LPAREN // ‘(‘ , RPAREN // ‘)’ , MOD, NOT, LOGIC_NOT, LOGIC_AND, LOGIC_OR, LOGIC_XOR, ASSIGN, LT, GT, //占2个字符 AND, OR, LE, GE, EQ, NE, } ; char *nextchar; string token; void settoken( char* expr){ token=expr; nextchar=expr; } int gettoken() { while(isspace(*nextchar)){ nextchar++; } switch(*nextchar) { case '+': nextchar++; return PLUS; case '-': nextchar++; return MINUS; case '*': nextchar++; return TIMERS; case '/': nextchar++; return OVER; case '%': nextchar++; return MOD; case '(': nextchar++; return LPAREN; case ')': nextchar++; return RPAREN; case '&':nextchar++; if(*nextchar=='&'){nextchar++;return AND;} else { return LOGIC_AND; } case '!':nextchar++; if(*nextchar=='='){ nextchar++;return NE;} else { return NOT; } case '|':nextchar++; if(*nextchar=='|'){ nextchar++;return OR;} else { return LOGIC_OR; } case '<':nextchar++; if(*nextchar=='='){ nextchar++;return LE;} else { return LT; } case '>':nextchar++; if(*nextchar=='='){ nextchar++;return GE;} else { return GT; } case '=':nextchar++; if(*nextchar=='='){ nextchar++;return EQ;} else { return ASSIGN; } default: break; } if(isalpha(*nextchar)) { char *beg = nextchar; char *end= nextchar; while(isalpha(*nextchar) || isdigit(*nextchar)) { nextchar++; } PRINT_TOKEN(beg,end); token=(beg,end); return ID; } // NUM 的词法识别分析 // NUM := 0(X|x)[digit|A-F|a-f]+ // NUM := [digit]+ // NUM := [digit]* \.[digit]+ char *last = nextchar; if(isdigit(*nextchar)) { char *beg = nextchar; char *end= nextchar; int digitType=0; //是16进制么 if(*nextchar=='0'&& (*(1+nextchar)=='x'||*(1+nextchar)=='X')) { nextchar +=2; //beg=nextchar; while(isdigit(*nextchar) ||(*nextchar>='a'&& *nextchar<='f')||(*nextchar>='A'&& *nextchar<='F')){ nextchar++; end++; } } else{ if(*nextchar=='0' && *(nextchar+1)!=NULL && (*(1+nextchar)!='x'||*(1+nextchar)!='X')){ fprintf(stderr,"not support 8 decimal,%s ",nextchar); } int dotOccur=0; while(isdigit(*nextchar) ||(*nextchar=='.'&&dotOccur==0)) { if(*nextchar=='.') { dotOccur=1; } nextchar++; end++; } if(dotOccur==0){ digitType= INT; } else{ digitType=FLOAT; } } PRINT_TOKEN(beg,end); if(beg==end){ fprintf(stderr,"parse error: %s",beg); } token= string(beg,end); if(digitType==INT){ return NUM_INT; } else{ return NUM_FLOAT; } } return ERROR; } //E := T+E |T //T := F*T | F //F := (E)|(!E)|ID void Statements(){ //Statements = [statement]+ } void Statement(){ //S :=;|{} //IF_STATEMENT='if'S; //ELSE_STATEMENT='else'S; //EXPR_STATEMENT=E; //BLOCK_STATEMENT ={S} } Value Assign(){ // id=E(); char *last = nextchar; int leftType = gettoken(); bool flag=false; string id; if(leftType==ID){ id = token; int opType = gettoken(); if(opType == ASSIGN){ flag=true; } } if(flag){ Value val = Assign(); symTable[id]=val; return val; } else{ nextchar = last; return E(); } } Value E() { //bug:二元运算符的字符个数 ^=,^,赋值运算符=和== Value left = T(); // 对应文法中的第一个Term Value r; int tokentype; while(*nextchar == '+' || *nextchar == '-' || *nextchar == '|' || *nextchar == '^' || *nextchar=='<' || *nextchar=='>' || *nextchar == '='|| (*nextchar == '!'&&*(nextchar+1)=='=') ) { tokentype = gettoken(); switch(tokentype) { case PLUS: //printf("PLUS"); r = T(); { Value result; result.type = (r.type ==FLOAT||left.type == FLOAT)?FLOAT:INT; result.setValue(left.getValue(left.type==INT?1:0.1) + r.getValue(r.type==INT?1:0.1)); left = result; } break; case MINUS: //printf("MINUS"); r = T(); { Value result; result.type = (r.type ==FLOAT||left.type == FLOAT)?FLOAT:INT; result.setValue(left.getValue(left.type==INT?1:0.1) - r.getValue(r.type==INT?1:0.1)); left = result; } break; case LOGIC_OR: //printf("LOGIC_OR"); r = T(); if(r.type ==FLOAT||left.type == FLOAT){ fprintf(stderr,"error, not support float LOGIC_OR"); } { Value result; result.type = INT; result.setValue((int)left.getValue(left.type==INT?1:0.1) | (int)r.getValue(r.type==INT?1:0.1)); left = result; } break; case LOGIC_XOR: r = T(); if(r.type ==FLOAT||left.type == FLOAT){ fprintf(stderr,"error, not support Float XOR"); } { Value result; result.type = INT; result.setValue((int)left.getValue(left.type==INT?1:0.1) ^(int) r.getValue(r.type==INT?1:0.1)); left = result; } break; case OR: r = T(); if(r.type ==FLOAT||left.type == FLOAT){ fprintf(stderr,"error, not support Float OR"); } { Value result; result.type = INT; result.setValue((int)left.getValue(left.type==INT?1:0.1) || (int)r.getValue(r.type==INT?1:0.1)); left = result; } break; case LT: //printf("LT"); r = T(); { Value result; result.type = INT; result.setValue(left.getValue(left.type==INT?1:0.1) < r.getValue(r.type==INT?1:0.1)); left = result; } break; case LE: r = T(); //printf("LE"); { Value result; result.type = INT; result.setValue(left.getValue(left.type==INT?1:0.1) <= r.getValue(r.type==INT?1:0.1)); left = result; } break; case GT: r = T(); //printf("GT"); { Value result; result.type = INT; result.setValue(left.getValue(left.type==INT?1:0.1) > r.getValue(r.type==INT?1:0.1)); left = result; } break; case GE: r= T(); { Value result; result.type = INT; result.setValue(left.getValue(left.type==INT?1:0.1) >= r.getValue(r.type==INT?1:0.1)); left = result; } break; case NE: r = T(); { Value result; result.type = INT; result.setValue(left.getValue(left.type==INT?1:0.1) != r.getValue(r.type==INT?1:0.1)); left = result; } break; default: break; } } return left; } Value T() { Value left; int tokentype; left = F(); Value r; while(*nextchar == '*' || *nextchar == '/' || *nextchar == '%' || *nextchar == '&' ) { tokentype =gettoken(); switch(tokentype) { case TIMERS: //printf("TIMERS"); r = T(); { Value result; result.type = (r.type ==FLOAT||left.type == FLOAT)?FLOAT:INT; result.setValue(left.getValue(left.type==INT?1:0.1) * r.getValue(r.type==INT?1:0.1)); left = result; } break; case OVER: r = T(); { Value result; result.type = (r.type ==FLOAT||left.type == FLOAT)?FLOAT:INT; result.setValue(left.getValue(left.type==INT?1:0.1) / r.getValue(r.type==INT?1:0.1)); left = result; } break; case MOD: r = T(); if(r.type ==FLOAT||left.type == FLOAT){ fprintf(stderr,"not support float % operator"); //left.type == FLOAT; //left.setValue(left.getValue() %r.getValue()); } { Value result; result.type = INT; result.setValue((int)left.getValue(left.type==INT?1:0.1) %(int) r.getValue(r.type==INT?1:0.1)); left = result; } break; case LOGIC_AND: r = T(); if(r.type ==FLOAT||left.type == FLOAT){ fprintf(stderr,"not support float & operator"); //left.type == FLOAT; //left.setValue(left.getValue() %r.getValue()); } { Value result; result.type = INT; result.setValue((int)left.getValue(left.type==INT?1:0.1) &(int) r.getValue(r.type==INT?1:0.1)); left = result; } break; case AND: //printf("AND"); r = T(); { Value result; result.type = INT; result.setValue((int)left.getValue(left.type==INT?1:0.1) &&(int) r.getValue(r.type==INT?1:0.1)); left = result; } break; default: break; } } return left; } Value F() { Value number; switch(gettoken()) { case ID: //printf("ID"); //number《-- 赋值id number = symTable[token]; break; case NUM_INT: //printf("NUM"); if(token[0]=='0' && token.size()>3 && (token[1]=='X'||token[1]=='x')) { number.type = INT; int v; sscanf(token.c_str(),"%x",&v); number.setValue(v); }else { number.type=INT; number.setValue(atoi(token.c_str())); } break; case NUM_FLOAT: number.type=FLOAT; number.setValue(atof(token.c_str())); break; case LPAREN: //printf("LPAREN"); number = E(); if(gettoken() != RPAREN){ printf("lost ')' in the expression \n"); } break; case NOT: //printf("NOT"); number = F(); number.setValue(!(int)number.getValue(1)); number.type = INT; break; case LOGIC_NOT: //printf("LOGIC_NOT"); number =E(); if(number.type!=INT){ fprintf(stderr,"not suport FLOAT !"); } number.setValue(~(int)number.getValue(1)); number.type = INT; break; case MINUS: number =E(); if(number.type==INT) { number.setValue(-number.getValue(1)); } else{ number.setValue(-number.getValue(0.1)); } default: break; } return number; } void PRINT_TOKEN(const char *beg,const char*end){ for(const char* p=beg;p!=end;p++){ //printf("%c",*p); } } map<string,Value> symTable; }; using namespace std; int main(int argc,char*argv[]) { Expression e; e.settoken("3+5*(7+2)"); Value v ; v= e.E(); if(v.type==INT){ cout<<"TYPE=INT"<<endl; } else{ cout<<"TYPE=FLOAT"<<endl; } cout<< ((v.type==INT)?v.getValue(1):v.getValue(0.1))<<endl; e.settoken("3+5<(7+1.0)"); v=e.E(); cout<< ((v.type==INT)?v.getValue(1):v.getValue(0.1))<<endl; e.settoken("3+(5.0<(7+1.0))||0"); v=e.E(); cout<<"expect:"<<(3+(5.0<(7+1.0))||0)<<"--real:"<< ((v.type==INT)?v.getValue(1):v.getValue(0.1))<<endl; e.settoken("3+5.0<=(7+1.0))&&(-7/6.0)<0"); v=e.E(); cout<<"expect:"<<(3+5.0<=(7+1.0)&&(-7/6.0)<0)<<"--real:"<<((v.type==INT)?v.getValue(1):v.getValue(0.1))<<endl; //printf("\n%d",e.E()); //单元运算符出错,因为是右结合的,递归下降分析比较复杂 e.settoken("(-7/6.0)"); v=e.E(); cout<<"expect:"<<(-7/6.0)<<"--real:"<<((v.type==INT)?v.getValue(1):v.getValue(0.1))<<endl; e.settoken("-(7/6.0)"); v=e.E(); cout<<"expect:"<<-(7/6.0)<<"--real:"<<((v.type==INT)?v.getValue(1):v.getValue(0.1))<<endl; e.settoken("-3+5"); v=e.E(); cout<<"expect:"<<-3+5<<"--real:"<<((v.type==INT)?v.getValue(1):v.getValue(0.1))<<endl; e.settoken("!3+9"); v=e.E(); cout<<"expect:"<<!3+9<<"--real:"<<((v.type==INT)?v.getValue(1):v.getValue(0.1))<<endl; e.settoken("!(3+9)"); v=e.E(); cout<<"expect:"<<!(3+9)<<"--real:"<<((v.type==INT)?v.getValue(1):v.getValue(0.1))<<endl; //e.settoken("3+6==(7+2)"); //printf("\n%d",e.E()); getchar(); return 0; }
上周五闲着无事,重新写了算术表达式,采用C/C++表达,目前支持 +,-,* 、%,()括号,运算符优先级
,同时支持整形和浮点型。
思路:
(1)递归下降分析,属性制导翻译(没有完全实现,但实现了部分,继承属性,综合属性)
E=T|T+E
T=T*F
F=id|(E)|-E|!E
(2)其实也支持其他很多运算符,如:比较运算符,(但没有特别处理运算符优先级,因此会出错,比如3<5+7,会翻译成(3<5)+7;逻辑运算符
(3)调用E()函数得到的是算术表达式的值,有机会的话,改造成,支持多个语句,以及语句块,嗯,用YacC和Lex试试。
相关推荐
编程实现给定算术表达式的递归下降分析器。算术表达式文法如下: EE+T | T TT*F | F F(E) | i
编程实现给定算术表达式的递归下降分析器。 算术表达式文法如下: E-->E+T|T T-->T*F|F F-->(E)|i
实现了c语言的算术表达式的语法分析,用的是递归下降分析法。程序简单易懂
<表达式> [+|-] <项>{(+|-) <项>} <项> <因子>{(*|/) <因子>} <因子> id|num| ‘(‘<表达式>‘)’ 预期显示success 或者fail
使用递归下降算法分析数学表达式 编译原理 课程设计报告
编程实现给定算术表达式的递归下降分析器。 算术表达式文法如下: EE+T | T TT*F | F F(E) | i
东北大学2022编译原理实验课——递归下降分析简单算术表达式(C++) 【问题描述】 1.设计简单算数表达式语法分析器算法;(用递归下降分析来实现) 2.编写代码并上机调试运行通过。 【输入形式】 简单算数表达式 ...
(使用Python实现,注释详尽)在词法分析器的基础上,采用递归下降的方法实现算术表达式的语法分析器,以加深对自上而下语法分析过程的理解。 1、对算术表达式文法: E→TE' E'→+TE'| -TE' |ε T→FT' T'→*FT'| /...
编译原理课程设计---递归下降分析程序的实现
基于递归下降的表达式语法分析器
1、使用递归下降分析算法分析表达式文法: exp ::= exp addop term | term addop ::= + | - term ::= term mulop factor | factor mulop ::= * | / factor ::= (exp) | number 其中number可以是多位的十进制数字串...
上课老师留的编译原理实验,应该是编译原理课都需要做的,用的是c++写的,主要是练习了递归下降分析法来计算表达式。
使用递归下降分析算法分析表达式文法: exp ::= exp addop term | term addop ::= + | - term ::= term mulop factor | factor mulop ::= * | / factor ::= (exp) | number 其中number可以是多位的十进制数字串...
以下描述算术表达式的LL(1)文法的递归下降分析程序构造 G[E]: E→TE′ E′→+TE′|ε T→FT′ T′→*FT′|ε F→(E)|i 说明:终结符号i为用户定义的简单变量,即标识符的定义。 要求具有如下功能: 1)从终端...
一、实验题目 设计一个简单的表达式语法分析器 (采用递归下降方法设计实现) 二、实验目的 1、 了解形式语言基础及其文法运算; 2、 熟悉语法分析原理及4种常用的... (本实验设计的是递归下降的表达式语法分析器)
使用C++ 实现的布尔表达式的递归下降 得到推导过程 词法分析 以及逆波兰式
递归下降分析器设计与实现.pdf
对每一个非终结符(分别代表一个语法单位)按其产生方式结构构造相应的语法子程序,以完成非终结符号所对应的语法单位的分析和识别任务。其中终结符号产生匹配命令,而非终结符号则产生过程调用命令。因为文法可以...
递归下降法分析表达式 程序代码 实验分析 编译原理 运行无误,编译正确,内含实验指导书
编译原理实验报告-算术表达式解释器的设计与实现