c++词法分析器
来源:互联网 发布:mysql如何查看 编辑:程序博客网 时间:2024/05/16 18:22
将词法分析结果放入vector向量中,为语法分析做准备
// MyLex.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include<stdio.h>#include<string.h>#include<vector>using namespace std;typedef struct{int syn;char name[10];double value;} TOKEN;void scaner();int isnumber(char* s);int isdigit(char c);int isalpha(char c);int isspace(char c);void strappend(char *text,char c);void skiperror();void skipcomment();void input();char prog[200],token[100];char *tok;int syn;double val = 0;char *rwtab[9]={"main","int","float","double","char","if","else","do","while"};vector<TOKEN> token_table;char *ValidVar="非法变量";char *NumError="数字错误";char *UnknownTok="未知符号";char eMsg[20];int _tmain(int argc, _TCHAR* argv[]){TOKEN temp_token;begin: memset(prog,0,sizeof(prog)); token_table.clear();//清空向量里的元素 syn = 100; printf("请输入语句:\n"); input();//获取输入字符串printf("(%5s,%5s)\n","编码","符号"); tok = prog; do{ scaner();temp_token.syn=syn;if( syn==20){temp_token.value=val;}else{strcpy(temp_token.name,token);}token_table.push_back(temp_token); }while (syn!=0);for(int i = 0; i < token_table.size();i++){switch(token_table[i].syn){case 20: printf("(%2d,%8g)\n",token_table[i].syn,token_table[i].value);break; case -1: printf("(-1,%8s)\n", token_table[i].name);break;default: printf("(%2d,%8s)\n",token_table[i].syn,token_table[i].name);break;}}getchar(); char ans; printf("继续?(Y/N):");//清空getchar()缓冲区 fflush(stdin); ans = getchar(); if(ans == 'Y' || ans == 'y'){putchar('\n');//跳转到开始再次执行词法分析 goto begin; }getchar();return 0;}//获取输入字符串void input(){ char c; do{ c=getchar(); strappend(prog,c); }while(c!='#');}void scaner(){ //清空token memset(token,0,sizeof(token));memset(eMsg,0,sizeof(eMsg)); //跳过空白字符for(;isspace(*tok);tok++){}//跳过注释skipcomment();//跳过空白字符for(;isspace(*tok);tok++){} //变量或关键字 if(isalpha(*tok)){ strappend(token,*tok); tok ++; for(;isalpha(*tok) || isdigit(*tok);tok++){ strappend(token,*tok); } // 变量 syn = 10; for(int n = 0; n < 9; n++){ //关键字 if(strcmp(token,rwtab[n]) == 0){ syn = n + 1; return; } } } //数字 else if(isnumber(tok)) { val=0;//数值 int flag = 1;//正负号 int e = 0;//指数 int sign = 1;//指数符号 if(*tok == '+'){ flag = 1;strappend(eMsg,*tok); tok++; }else if(*tok == '-'){ flag = -1;strappend(eMsg,*tok); tok++; } for(;isdigit(*tok);tok++){ val = val * 10 + (*tok) - '0';strappend(eMsg,*tok); } //浮点数 if(*tok == '.'){strappend(eMsg,*tok); tok++;//小数点后不带数字为错误并且返回if(!isdigit(*tok)){strcpy(token,NumError);strcat(token,":");strcat(token,eMsg);return;} for(;isdigit(*tok);tok++){ val = val * 10 + (*tok) - '0'; e --;strappend(eMsg,*tok); } }//科学计数法 if(*tok == 'e' || *tok == 'E'){strappend(eMsg,*tok); tok ++; int i = 0; if(*tok == '+'){ sign = 1;strappend(eMsg,*tok); tok ++; } else if(*tok == '-'){ sign = -1;strappend(eMsg,*tok); tok ++; }if(!isdigit(*tok)){//如果不是数字,错误syn = -1;strcpy(token,NumError);strcat(token,":");strcat(token,eMsg);return;} for(;isdigit(*tok);tok++){ i = i * 10 + (*tok) - '0'; } e += sign * i; }//计算出数字的值 while(e > 0){ val *= 10.0; e --; } while(e < 0){ val *= 0.1; e ++; } val *= flag; syn=20;/* 似乎是语法分析的内容数字后出现字母 if(isalpha(*tok)){ErrorType = NumError;syn=-1;//跳过数字后的所以字母skiperror();return;}*/ } else switch(*tok){ case'<':strappend(token,*tok);tok++; switch(*tok){// case '>':syn = 21; strappend(token,*tok);tok++;break; case '=':syn = 35; strappend(token,*tok);tok++;break; default: syn = 34; break; } break; case'>':strappend(token,*tok);tok++; switch(*tok){ case '=': syn = 33; strappend(token,*tok);tok++;break; default: syn = 32; break; } break;/*木有冒号了,T_T case':':strappend(token,*tok);tok++; switch(*tok){ case '=': syn = 18; strappend(token,*tok);tok++;break; default: syn = 17; ;break; } break;*/case'!':strappend(token,*tok);tok++;switch(*tok){case '=': syn = 37; strappend(token,*tok);tok++;break;default: syn = -1; break;}break;case '=':strappend(token,*tok);tok++;switch(*tok){case '=':syn=36;strappend(token,*tok);tok++;break;default: syn=21;break;}break; case'+':syn=22;token[0]=*tok++;break; case'-':syn=23;token[0]=*tok++;break; case'*':syn=24;token[0]=*tok++;break; case'/':syn=25;token[0]=*tok++;break;// case'=':syn=21;token[0]=*tok++;break; case';':syn=31;token[0]=*tok++;break; case'(':syn=26;token[0]=*tok++;break; case')':syn=27;token[0]=*tok++;break; case',':syn=30;token[0]=*tok++;break;case'#':syn=0 ;token[0]=*tok++;break;case'{':syn=28;token[0]=*tok++;break;case'}':syn=29;token[0]=*tok++;break;case'[':syn=40;token[0]=*tok++;break;case']':syn=41;token[0]=*tok++;break;default: syn=-1;tok++;strcpy(token,UnknownTok);strcat(token,":");strappend(token,*(tok-1));break; }}//向字符串添加字符void strappend(char* des,char c){ int pos = strlen(des); *(des + pos) = c; *(des + pos + 1) = '\0';}//有符号数字int isnumber(char *s){//如果上个单词是数字或变量,+—当作运算符,否则按符号if(syn == 11 || syn == 20){return isdigit(*tok);} return (*s=='+' || *s =='-') && isdigit(*(tok+1)) || isdigit(*s);}//空格字符int isspace(char c){ return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\v' || c == '\f' || c == '\0');}//字母int isalpha(char c){return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');}//数字int isdigit(char c){return c >= '0' && c <= '9';}//跳过错误字符//此方法不使用void skiperror(){for(;isdigit(*tok) || isalpha(*tok) || *tok == '.' || *tok == '_';tok++){}}//跳过注释void skipcomment(){if(*tok=='/' && *(tok+1)=='*'){tok+=2;while(*tok!='\0' && *tok!='#'){if(*tok=='*' && *(tok+1)=='/'){tok+=2;return;}tok++;}}}
- c语言词法分析器
- C语言词法分析器
- 词法分析器(C语言版)
- 词法分析器 c语言
- C语言词法分析器
- 词法分析器 c 语言
- 词法分析器 c语言
- C语言词法分析器源代码
- 【C语言/vs2010】词法分析器
- C语言实现词法分析器
- C语言实现词法分析器
- C语言实现词法分析器
- c词法分析器(简易C语言)
- 用c实现pascal词法分析器
- 用c写的词法分析器
- 关于简单c的词法分析器
- JAVA版 C语言词法分析器
- C语言实现的词法分析器
- 编写安全代码——小心有符号数的右移操作
- 软考学习--PV操作一--概念解析
- C++学习之旅——结构体和联合体的区别,以及数据对齐方式影响内存大小
- red hat 企业版更新源的添加
- 解读Python内存管理机制
- c++词法分析器
- Foreign Language_english_限定词
- 帧动画和旋转
- COJ 1373 STL中的map每日四水
- A star 寻路算法实现(C++版本)
- 【PAT Advanced Level】1006. Sign In and Sign Out (25)
- hashCode和equals方法的理解
- 编写一个字符串复制函数mystrcopy(char*s1,char*s2,int m),将字符串s2中从第m个开始全部字符都复制到s1中
- hdu4762之大数乘法