标签:
工程代码http://download.csdn.net/detail/fulianzhou/9541833
config.h
/***** *********/ #ifndef _CONFIG_H_ #define _CONFIG_H_ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> //#define LEX_OUTPUT #define MAXSTRLEN 1024 #define UNDEFINE_DATA -1 // 单词类型 const enum TYPE{ em_start = 1,// # em_add, // + em_sub, // - em_mul, // * em_div, // / em_equ, // = em_left, // ( em_right, // ) em_int, // int em_real, // real em_mark, // mark em_sem, // ; em_com, // , em_default, // 无法识别 }; // 元素数据 typedef struct { TYPE type; char *name; union{ int int_dat; double real_dat; }value; }ElemType; // 优先关系表 const char g_cPriorList[10][10]={ /* + - * / = ( ) i V # */ /* + */ '>', '>', '<', '<', ' ', '<', '>', '<', '<', ' ', // 0 /* - */ '>', '>', '<', '<', ' ', '<', '>', '<', '<', ' ', // 1 /* * */ '>', '>', '>', '>', ' ', '<', '>', '<', '<', ' ', // 2 /* / */ '>', '>', '>', '>', ' ', '<', '>', '<', '<', ' ', // 3 /* = */ '<', '<', '<', '<', ' ', '<', '>', '<', '<', ' ', // 4 /* ( */ '<', '<', '<', '<', ' ', '<', '=', '<', '<', ' ', // 5 /* ) */ '>', '>', '>', '>', ' ', ' ', '>', ' ', ' ', '>', // 6 /* i */ '>', '>', '>', '>', ' ', ' ', '>', ' ', ' ', '>', // 7 /* V */ '>', '>', '>', '>', '=', ' ', '>', ' ', ' ', '>', // 8 /* # */ '>', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '=', // 9 }; // 查询优先关系表,得优先关系 char GetPrior(TYPE left,TYPE right); // 形成数据 ElemType FormElemData(char *name,TYPE type,double data); // 显示元素内容 void DispElem(ElemType item); #endif
config.cpp
#include "config.h" // 形成数据结点 ElemType FormElemData(char *name,TYPE type,double data){ ElemType item; item.name = (char*)calloc(sizeof(char),strlen(name)+1); strcpy(item.name,name); item.type = type; if(item.type == em_int) item.value.int_dat = (int)data; else if(item.type == em_real) item.value.real_dat = data; else item.value.real_dat = data; return item; } // 显示元素内容 void DispElem(ElemType item){ printf("(%s,%d,%g)\n",item.name,item.type,item.type == em_int ? item.value.int_dat : item.value.real_dat); } // 根据有限关系表获取坐标值 static int GetPos(TYPE type){ switch(type){ case em_add:return 0; case em_sub:return 1; case em_mul:return 2; case em_div:return 3; case em_equ:return 4; case em_left:return 5; case em_right:return 6; case em_int: case em_real:return 7; case em_mark:return 8; case em_start:return 9; } return -1; } // 查询优先关系表,得优先关系 char GetPrior(TYPE left,TYPE right){ int iLeft = GetPos(left); int iRight = GetPos(right); if(iLeft >= 0 && iRight >= 0){ return g_cPriorList[iLeft][iRight]; } else{ printf("Error, can not recognition type.\n"); return '-'; } }
grammar_analysis.h
#ifndef _GRAMMAR_ANALYSIS_H_ #define _GRAMMAR_ANALYSIS_H_ #include "config.h" #include "linklist.h" #include "linkstack.h" // 语法分析 int Grammar_Analysis(PT_List list); #endif
grammar_analysis.cpp
#include "grammar_analysis.h" static int Grammar_CheckFormat(PT_List list){ int i; TYPE t1,t2; int l = LinkList_GetLength(list); TYPE t = LinkList_GetNode(list,1)->data.type; if(!(t == em_int || t==em_real || t==em_left)) return 0; for(i=1;i < l;i++){ if(LinkList_GetNode(list,i)->data.type == em_mark) return 0; if(LinkList_GetNode(list,i)->data.type == em_default) return 0; if(LinkList_GetNode(list,i)->data.type == em_equ) return 0; if(i>1 && i < l){ t1 = LinkList_GetNode(list,i-1)->data.type; t2 = LinkList_GetNode(list,i)->data.type; if((t1 == em_left && t2 == em_right) || (t1 == em_right && t2 == em_left)) // (),)( return 0; if((t1 == em_add || t1 == em_sub || t1 == em_mul || t1 == em_div) && (t2 == em_add || t2 == em_sub || t2 == em_mul || t2 == em_div)) // ++,+-,+/... return 0; if(t1 == em_int || t1 == em_real){ if(t2 == em_add || t2 == em_sub || t2 == em_mul || t2 == em_div || t2 == em_right) {} else // 2 2,2(, return 0; } if(t1 == em_add || t1 == em_sub || t1 == em_mul || t1 == em_div){ if(t2 == em_int || t2 == em_real || t2 == em_left){ } else // +),++,... return 0; } } } return 1; } // 计算 Data EvaluateExpression(PT_List ptlist,int *flag) { int iIndex = 3; int len = LinkList_GetLength(ptlist); //printf("len = %d\n",len); *flag = 1; // 先置为合格 ElemType tmpData; LinkList OPTR,OPND; ListInit(OPTR); //寄存运算符 ListInit(OPND); // 寄存数字 Push_sign(OPTR,em_start); /* 获取下一个 */ if(iIndex < len){ /* */ tmpData = LinkList_GetNode(ptlist,iIndex)->data; //printf("GetNode: iIndex:%d,name:%s\n",iIndex,tmpData.name); iIndex++; } else{ tmpData.type = em_start; } if(tmpData.type == em_int || tmpData.type == em_real){ Push_num(OPND,tmpData.type == em_int ? atoi(tmpData.name):atof(tmpData.name));//Push_num(OPND,tmpData.value.real_dat); /* 获取下一个 */ if(iIndex < len){ /* */ tmpData = LinkList_GetNode(ptlist,iIndex)->data; //printf("GetNode: iIndex:%d,name:%s\n",iIndex,tmpData.name); iIndex++; } else{ tmpData.type = em_start; } } while(tmpData.type != em_start || Get_top_sign(OPTR) != em_start) { if(tmpData.type == em_int || tmpData.type == em_real){ Push_num(OPND,tmpData.type == em_int ? atoi(tmpData.name):atof(tmpData.name)); /* 获取下一个 */ if(iIndex < len){ /* */ tmpData = LinkList_GetNode(ptlist,iIndex)->data; //printf("GetNode: iIndex:%d,name:%s\n",iIndex,tmpData.name); iIndex++; } else{ tmpData.type = em_start; } } switch(/*GetPrior*/Precede(Get_top_sign(OPTR),tmpData.type)) { case '<': Push_sign(OPTR,tmpData.type); /* 获取下一个 */ if(iIndex < len){ /* */ tmpData = LinkList_GetNode(ptlist,iIndex)->data; //printf("GetNode: iIndex:%d,name:%s\n",iIndex,tmpData.name); iIndex++; } else{ tmpData.type = em_start; } break; case '=': Pop_sign(OPTR); /* 获取下一个 */ if(iIndex < len){ /* */ tmpData = LinkList_GetNode(ptlist,iIndex)->data; //printf("GetNode: iIndex:%d,name:%s\n",iIndex,tmpData.name); iIndex++; } else{ tmpData.type = em_start; } break; case '>':{ double s = Operate(Pop_num(OPND),Pop_sign(OPTR),Pop_num(OPND)); //printf("s = %g\n",s); Push_num(OPND,s); break; } case '-': case ' ': // 出现不合法的语法单元,退出 *flag = 0; break; } if(*flag == 0) { //printf("flag = 0,break;\n"); break; } } //printf("Out!tmpdata.type = %d,top sign=%d\n",tmpData.type,Get_top_sign(OPTR)); return Pop_num(OPND); } // 语法分析 int Grammar_Analysis(PT_List list){ PT_List ptlist = list; if(!(LinkList_GetNode(ptlist,1)->data.type == em_mark && LinkList_GetNode(ptlist,2)->data.type == em_equ)){ LinkList_DispAllRaw(list); printf("\t --> can not calculate.\n"); return 0; } else { ptlist=ptlist->next; ptlist=ptlist->next; if(Grammar_CheckFormat(ptlist) == 0) { LinkList_DispAllRaw(list); printf("\t --> can not calculate.\n"); return 0; } } int flag = 1; double sum = EvaluateExpression(list,&flag); LinkList_DispAllRaw(list); if(flag){ printf("\t --> %s%s%g;\n",LinkList_GetNode(list,1)->data.name,LinkList_GetNode(list,2)->data.name,sum); } else puts("\t --> can not calculate.\n"); return 0; }
lexical_analysis.h
#ifndef _LEXICAL_ANALYSIS_ #define _LEXICAL_ANALYSIS_ #include "config.h" #include "linklist.h" // 词法分析 PT_List ParseWord(char strInput[]); #endif
Lexical_analysis.cpp
/* 输入串必须以'#'号结尾 */ #include "lexical_analysis.h" #include "linklist.h" /* 类别标志 */ TYPE g_type = em_default; void OutputStr(char str[],int flag){ switch(flag){ case em_int:fprintf(stdout,"(%s,%d)\t整数\n",str,flag);break; case em_real:fprintf(stdout,"(%s,%d)\t实数\n",str,flag);break; case em_default:fprintf(stdout,"(%s,%d)\t无法识别\n",str,flag);break; case em_mark:fprintf(stdout,"(%s,%d)\t标识符\n",str,flag);break; } } // 解析单词 PT_List ParseWord(char strInput[]){ int i,j; char strTemp[MAXSTRLEN] = { 0 }; // 临时数组,用于保存单词 int iLen = 0; // 临时数组长度 int iDot; // 小数点出现标识符 PT_List ptlist = (PT_List)calloc(sizeof(T_List),1); LinkList_Init(ptlist); g_type = em_default; // 标志为未处理 for(i=0;strInput[i] && strInput[i] != '#';i++){ if(isdigit(strInput[i])){ // 如果是数字 iDot = 0; // 小数点没有出现过 memset(strTemp,0,sizeof(strTemp)); // 清空临时数组 iLen = 0; // 临时数组长度为0 g_type = em_int; // 标志为整数 for(j=i;strInput[i] && strInput[j] != '#';j++){ if(strInput[j] == '.'){ // 如果出现小数点x if(iDot == 0){ // 如果小数点没有出现过 iDot = 1; // 标识为小数点已经出现 strTemp[iLen++] = strInput[j]; // 存在临时数组中 g_type = em_default; // 标志为无法识别 } else{ // 第二次出现小数点出错 j--; break; } } else if(isdigit(strInput[j])){ // 如果是数字 strTemp[iLen++] = strInput[j]; if(g_type == em_default) g_type = em_real; } else{ j--; break; } } #ifdef LEX_OUTPUT OutputStr(strTemp,g_type); #endif if(g_type == em_default){ LinkList_AddNode(ptlist,FormElemData(strTemp,g_type,UNDEFINE_DATA)); } else{ LinkList_AddNode(ptlist,FormElemData(strTemp,g_type,g_type == em_int ? atoi(strTemp) : atof(strTemp))); } memset(strTemp,0,sizeof(strTemp)); // 清空临时数组 iLen = 0; // 临时数组长度为0 i = j; } else if(isalpha(strInput[i])){ // 如果是以字母开头 memset(strTemp,0,sizeof(strTemp)); iLen = 0; g_type = em_mark; // 标记为标识符 for(j=i;strInput[i] && strInput[j] != '#';j++){ if(isalpha(strInput[j]) || isdigit(strInput[j])){ // 如果是数字或者字母 strTemp[iLen++] = strInput[j]; } else{ j--;// 否则 break; } } #ifdef LEX_OUTPUT OutputStr(strTemp,g_type); #endif LinkList_AddNode(ptlist,FormElemData(strTemp,g_type,UNDEFINE_DATA)); iLen = 0; memset(strTemp,0,sizeof(strTemp)); i = j; } else if(isspace(strInput[i])) continue; else{ switch(strInput[i]){ case '+':g_type = em_add;break; case '-':g_type = em_sub;break; case '*':g_type = em_mul;break; case '/':g_type = em_div;break; case '=':g_type = em_equ;break; case ';':g_type = em_sem;break; case ',':g_type = em_com;break; case '(':g_type = em_left;break; case ')':g_type = em_right;break; default:g_type = em_default; } strTemp[0] = strInput[i]; strTemp[1] = '\0'; LinkList_AddNode(ptlist,FormElemData(strTemp,g_type,UNDEFINE_DATA)); #ifdef LEX_OUTPUT fprintf(stdout,"(%c,%d)",strInput[i],g_type); if(g_type == em_add || g_type == em_sub || g_type == em_mul || g_type == em_div || g_type == em_equ) printf("\t运算符\n"); else if(g_type == em_sem || g_type == em_com) printf("\t界符\n"); else printf("\t无法识别\n"); #endif } } return ptlist; }
linklist.h
#ifndef _LINKLIST_H_ #define _LINKLIST_H_ #include "config.h" typedef struct tLNode{ tLNode *next; ElemType data; }T_List,*PT_List; // 添加结点 int LinkList_AddNode(PT_List ptlist,ElemType item); // 初始化链表 void LinkList_Init(PT_List ptlist); // 添加结点 int LinkList_AddNode(PT_List ptlist,ElemType item); // 显示所有节点 void LinkList_DispAll(PT_List ptlist); // 获取链表长度 int LinkList_GetLength(PT_List ptlist); // 获取指定位置结点 PT_List LinkList_GetNode(PT_List ptlist,int pos); // 显示所有节点名字 void LinkList_DispAllRaw(PT_List ptlist); // 销毁链表 void LinkList_Destroy(PT_List ptlist); #endif
Linklist.cpp
#include "linklist.h" // 初始化链表 void LinkList_Init(PT_List ptlist){ ptlist->data = FormElemData("<head>",em_default,UNDEFINE_DATA); ptlist->next = NULL; } // 添加结点 int LinkList_AddNode(PT_List ptlist,ElemType item){ PT_List tmplist = ptlist; while(tmplist->next != NULL){ tmplist = tmplist->next; } PT_List newNode = (PT_List)calloc(sizeof(T_List),1); newNode->next = NULL; newNode->data = item; tmplist->next = newNode; return 1; } // 显示所有节点 void LinkList_DispAll(PT_List ptlist){ PT_List tmplist = ptlist; while(tmplist->next != NULL){ tmplist = tmplist->next; DispElem(tmplist->data); } } // 显示所有节点名字 void LinkList_DispAllRaw(PT_List ptlist){ PT_List tmplist = ptlist; while(tmplist->next != NULL){ tmplist = tmplist->next; //DispElem(tmplist->data); printf("%s",tmplist->data.name); } } // 获取链表长度 int LinkList_GetLength(PT_List ptlist){ int len = 0; PT_List tmplist = ptlist; while(tmplist->next != NULL){ tmplist = tmplist->next; len++; } return len; } // 获取指定位置结点 PT_List LinkList_GetNode(PT_List ptlist,int pos){ if(pos <= 0 || pos > LinkList_GetLength(ptlist)){ printf("Out of range.\n"); return NULL; } int num = 1; PT_List tmpList = ptlist; while(tmpList->next != NULL && num <= pos){ tmpList = tmpList->next; num++; } return tmpList; } // 获取下一个 PT_List LinkList_GetNext(PT_List ptlist){ if(ptlist->next != NULL){ PT_List tmpList = ptlist; ptlist = ptlist->next; return tmpList; } return NULL; } // 销毁链表 void LinkList_Destroy(PT_List ptlist){ while(ptlist->next){ PT_List tmplist = ptlist; ptlist = ptlist->next; free(tmplist); } free(ptlist); }
linkstack.h
#ifndef _LINKSTACK_H_ #define _LINKSTACK_H_ #define OK 1 #define NO 0 #define ERROR 0 #define OVERFLOW -1 typedef TYPE Sign; typedef int Status; typedef double Data; typedef struct LNode { Sign sign; Data num; struct LNode *prior; }LNode,*LinkList; //初始化 Status ListInit(LinkList &L); //数字入栈 Status Push_num(LinkList &L,Data e); //字符入栈 Status Push_sign(LinkList &L,Sign e); // 字符出栈 Sign Pop_sign(LinkList &L); //数字出栈 Data Pop_num(LinkList &L); // 判断栈空 Status Empty(LinkList L); // 得栈顶字符元素 Sign Get_top_sign(LinkList L); // 判断优先性 char Precede(TYPE c1,TYPE c2); // 运算 double Operate(double x,TYPE c,double y); #endif
linkstack.cpp
#include "config.h" #include "linkstack.h" Status ListInit(LinkList &L) ///初始化 { L=(LinkList)malloc(sizeof(LNode)); L->prior=NULL; return OK; } Status Push_num(LinkList &L,double e) ///数字入栈 { LinkList p=(LinkList)malloc(sizeof(LNode)); p->num=e; p->prior=L; L=p; //printf("Push_num:%.2f\n",e); return OK; } Status Push_sign(LinkList &L,Sign e) /// 字符入栈 { LinkList p=(LinkList)malloc(sizeof(LNode)); p->sign=e; p->prior=L; L=p; //printf("Push_sign:%d\n",e); return OK; } Sign Pop_sign(LinkList &L) /// 字符出栈 { if(L->prior!=NULL) { LinkList p=L; Sign x=L->sign; L=L->prior; free(p); //printf("Pop_sign:%d\n",x); return x; } } Data Pop_num(LinkList &L) ///数字出栈 { if(L->prior!=NULL) { LinkList p=L; Data a=L->num; L=L->prior; free(p); //printf("Pop_num:%g\n",a); return a; } } Status Empty(LinkList L) /// 判断栈空 { if(L->prior==NULL) return 1; return 0; } Sign Get_top_sign(LinkList L) /// 得栈顶字符元素 { if(L->prior!=NULL) return L->sign; } char Precede(TYPE c1,TYPE c2) /// 判断优先性 { if((c1==em_add||c1== em_sub) && (c2==em_add||c2==em_sub||c2==em_right||c2==em_start)) return '>'; else if((c1==em_add||c1==em_sub) && (c2==em_mul||c2==em_div||c2==em_left)) return '<'; if((c1==em_mul||c1==em_div) && (c2==em_add||c2==em_sub||c2==em_mul||c2==em_div||c2==em_right||c2==em_start)) return '>'; else if((c1==em_mul||c1==em_div) && c2==em_left ) return '<'; if(c1==em_left && (c2==em_add||c2==em_sub||c2==em_mul||c2==em_div||c2==em_left)) return '<'; else if(c1==em_left && c2==em_right) return '='; if(c1==em_right) return '>'; if(c1==em_start && c2==em_start) return '='; else return '<'; } // 运算 double Operate(double x,TYPE type,double y){ double s = 0; switch(type){ case em_add:s = x + y;break; case em_sub:s = x - y;break; case em_mul:s = x * y;break; case em_div:s = x / y;break; } return s; }
#include "lexical_analysis.h" #include "grammar_analysis.h" int main(int argc,char *argv[]){ char strInput[MAXSTRLEN] = { 0 }; char c; int iLen = 0; printf("Input lines.\n\tevery sentence end by ';',end of '#':\n"); while(1){ memset(strInput,0,sizeof(strInput)); iLen = 0; c = 0; while((c = (char)getc(stdin)) != '#') strInput[iLen++] = c; strInput[iLen] = '\0'; PT_List ptList = ParseWord(strInput); int listlen = LinkList_GetLength(ptList); //printf("length = %d\n",listlen); puts("lexical analysis:"); LinkList_DispAll(ptList); puts(""); puts("grammar analysis:"); int n = 1; ElemType e; while(n <= LinkList_GetLength(ptList)){ PT_List list = (PT_List)calloc(sizeof(T_List),1); LinkList_Init(list); while(n < listlen && (e = LinkList_GetNode(ptList,n)->data).type != em_sem){ // 找出一句 LinkList_AddNode(list,e); n++; } LinkList_AddNode(list,LinkList_GetNode(ptList,n)->data); n++; /* 开始语法分析 */ Grammar_Analysis(list); LinkList_Destroy(list); } printf("\ninput new lines:\n"); } return 0; }
标签:
原文地址:http://blog.csdn.net/fulianzhou/article/details/51590240