博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++词法分析器
阅读量:4294 次
发布时间:2019-05-27

本文共 6572 字,大约阅读时间需要 21 分钟。

将词法分析结果放入vector向量中,为语法分析做准备

// MyLex.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include
#include
#include
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_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++; } }}

转载地址:http://pvuws.baihongyu.com/

你可能感兴趣的文章
docker 启动已经停止的容器
查看>>
order by 排序原理及性能优化
查看>>
Lock重入锁
查看>>
docker安装 rabbitMq
查看>>
git 常用命令 入门
查看>>
linux安装docker
查看>>
关闭selinx nginx无法使用代理
查看>>
shell 脚本部署项目
查看>>
spring cloud zuul网关上传大文件
查看>>
springboot+mybatis日志显示SQL
查看>>
工作流中文乱码问题解决
查看>>
maven打包本地依赖包
查看>>
spring boot jpa 实现拦截器
查看>>
jenkins + maven+ gitlab 自动化部署
查看>>
Pull Request流程
查看>>
Lambda 表达式
查看>>
函数式数据处理(一)--流
查看>>
java 流使用
查看>>
java 用流收集数据
查看>>
java并行流
查看>>