使用C语言编写程序对C语言程序进行语法和词法分析。

注注注注注:Dev需先配置C++11的环境,lex.h与语法分析程序同一目录下

目录

1.程序要求

1.1词法分析

1.2语法分析

2.原理图

2.1词法

2.2种别码表

2.3语法

3.运行截图

3.1词法分析

3.2语法分析

4.源码

4.1词法分析(lex.h)

4.2语法分析


1.程序要求

1.1词法分析

已知待分析的C语言子集的词法:

1. 关键字: main  if  else  int  while  char 均为小写。

2.专用符号: = + - * / < <= > >=  ==  !=   ; , {  }  (  )

3、其他标记ID和NUM通过以下正则式定义: ID: letter(letter|digit)* NUM: digitdigit* letter→a|b|c|d…|z|A|B|C…|Z digit →0|1|2|3|4|5|6|7|8|9

4、空格由空白、制表符、换行符组成,用来分隔ID、NUM、专用符号与关键字,词法分析阶段常被忽略。

要求: 设计、编制并调试一个词法分析程序

输入:源程序文件

输出:二元组(syn,token或sum)构成的序列(文件),其中:syn为单词种别码,token为存放的单词自身字符串,sum为整型常量。

1.2语法分析

在上机(一)词法分析的基础上,采用递归子程序法或其他适合的语法分析方法,实现其语法分析程序。要求编译后能检查出语法错误。

2.原理图

2.1词法

2.2种别码表

单词符号

种别码

单词符号

种别码

单词符号

种别码

main

1

+

22

;

31

 int

2

-

23

>

32

 char

3

*

24

<

33

if

4

/

25

>=

34

else

5

(

26

<=

35

while

6

)

27

==

36

ID

10

{

28

!=

37

NUM

20

}

29

=

21

,

30

2.3语法

3.运行截图

3.1词法分析

3.2语法分析

4.源码

4.1词法分析(lex.h)

#ifndef LEX_H
#define LEX_H
#include"lex.h" #define E 65535
#define EOI -1
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cctype>
#include<vector>
#include<map>
using namespace std;
int line;
int column,cc;
typedef struct CI{int line;int column;int type;
}Ci;
map<string,int> mp{{"ID",10},{"INT",20},{"<",33},{"<=",35},{"<>",36},{"!=",37},{">",32},{">=",34},{"=",21},{"+",22},{"-",23},{"*",24},{"/",25},{"(",26},{")",27},{"{",28},{"}",29},{",",30},{";",31},{"[",32},{"]",33}, {"int",2},{"char",3},{"float",7},{"main",1},{"switch",12},{"double",8},{"case",10},{"for",9},{"if",4},{"auto",9},{"else",5},{"do",11},{"while",6},{"void",13},{"static",14},{"return",15},{"break",16},{"struct",17},{"const",18},{"union",19},{"typedef",20},{"enum",21}};
int lookup(string TOKEN){if(mp.find(TOKEN)==mp.end())return -1;else return mp[TOKEN];
}
void out(FILE* fout,string str,int id,string explain,vector<Ci> &v){fprintf(fout,"line_%-5d%-9s%-5d%-9s\n",(line+1),str.c_str(),id,explain.c_str());v.push_back({line+1,column,id});
}
void print_error(FILE* fout,char ch,vector<Ci> &v){fprintf(fout,"line_%-5d%-9c%-5c%-9s\n",(line+1),ch,'E',"异常字符");v.push_back({line+1,column,E});
}
vector<Ci> analysis(FILE* fin,FILE* fout){char ch;int i,c;string TOKEN;vector<Ci> v;column=1;fprintf(fout,"%-10s%-9s%-5s%-9s\n","line_num","string","num","explain");while((ch=fgetc(fin))!=EOF){if(ch==' '){column++;continue;}if(ch=='\t'){column+=4;continue;}if(ch=='\n'){line++;column=1; continue;}if(isalpha(ch)){//标识符或关键字 cc=column;TOKEN=string(1,ch);ch=fgetc(fin); cc++;while(isalnum(ch)){cc++;TOKEN+=ch;ch=fgetc(fin);}fseek(fin,-1,1);//回退c=lookup(TOKEN);if(c==-1)out(fout,TOKEN,mp["ID"],"标识符",v);//是标识符(1) else out(fout,TOKEN,c,"关键字",v);//是关键字column=cc;}else if(isdigit(ch)){cc=column;TOKEN=string(1,ch);ch=fgetc(fin);cc++;while(isdigit(ch)){cc++;TOKEN+=ch;ch=fgetc(fin);}fseek(fin,-1,1);//回退out(fout,TOKEN,mp["INT"],"无符号整数",v);column=cc;}else{switch(ch){//运算符 case '<':{ch=fgetc(fin);cc=column+2;if(ch=='=')out(fout,"<=",mp["<="],"运算符",v);else if(ch=='>')out(fout,"<>",mp["<>"],"运算符",v);else{cc--;fseek(fin,-1,1);//回退out(fout,"<",mp["<"],"运算符",v);  }column=cc;break;}case '>':{ch=fgetc(fin);cc=column+2;if(ch=='=')out(fout,">=",mp[">="],"运算符",v);else{cc--;fseek(fin,-1,1);//回退out(fout,">",mp[">"],"运算符",v);   }column=cc;break;}case '=':out(fout,string(1,ch),mp["="],"运算符",v);column++;break;case '+':out(fout,string(1,ch),mp["+"],"运算符",v);column++;break;case '-':out(fout,string(1,ch),mp["-"],"运算符",v);column++;break;case '*':out(fout,string(1,ch),mp["*"],"运算符",v);column++;break;case '/':out(fout,string(1,ch),mp["/"],"运算符",v);column++;break;//分界符 case '(':out(fout,string(1,ch),mp["("],"分界符",v);column++;break;case ')':out(fout,string(1,ch),mp[")"],"分界符",v);column++;break;case '[':out(fout,string(1,ch),mp["["],"分界符",v);column++;break;case ']':out(fout,string(1,ch),mp["]"],"分界符",v);column++;break;case '{':out(fout,string(1,ch),mp["{"],"分界符",v);column++;break;case '}':out(fout,string(1,ch),mp["}"],"分界符",v);column++;break;case ',':out(fout,string(1,ch),mp[","],"分界符",v);column++;break;case ';':out(fout,string(1,ch),mp[";"],"分界符",v);column++;break;default:print_error(fout,ch,v);column++;break;}}}v.push_back({line+1,column,EOI});return v;
}
#endif

4.2语法分析

#include<iostream>
#include"lex.h"
using namespace std;
int index;
FILE *fin,*fout,*flog;
vector<Ci> v;
void advance(){index++;
}
bool match(string s){if(index>=v.size())return 0;if(v[index].type==E){printf("line:%-3d,column:%-3d 语法错误\n",v[index].line,v[index].column); advance();return 0;} else return v[index].type==mp[s];
}
bool match(int ch){if(index>v.size())return 0;else return v[index].type==ch;
}
void ERROR(string e){printf("line:%-3d,column:%-3d %s\n",v[index].line,v[index].column,e.c_str());fprintf(flog,"line:%-3d,column:%-3d %s\n",v[index].line,v[index].column,e.c_str());fclose(flog);exit(111111);
}
void expression();
void block();
void cacu_operator(){if(match("<")||match("<=")||match(">")||match(">=")||match("<>")||match("!=")){advance(); }else{ERROR("错误的运算符");}
}
void condition(){expression();cacu_operator();expression();
}
void Y(){ if(match("ID")||match("INT")){advance();}else if(match("(")){advance(); expression();if(!match(")"))ERROR("括号不匹配 缺少')'");else advance();}else{ERROR("缺数字或变量");}
}
void X(){while(1){Y();if(match("*")||match("/")){advance();continue;}else{break;}}
}void giveValue(){advance();if(match("=")){advance(); expression(); }else{ERROR("没有'='");}
}
void check(){advance();if(match("(")){advance();condition();if(match(")")){advance();block();}else{ERROR("无')'");}}else{ERROR("无'('");}
}
void circulation(){advance();if(match("(")){advance();condition();if(match(")")){advance();block();}else{ERROR("无')'");}}else{ERROR("无'('");}
}
void expression(){while(1){X();if(match("+")||match("-")){advance();continue;}else{break;}}
}void sentence(){if(match("ID")){giveValue();}else if(match("if")){check();}else if(match("while")){circulation();}else if(match("INT")){ERROR("不能是数字");}else if(match(E)){ERROR("语法错误");advance();sentence(); }else{ERROR("标识符不合法");}
}
void sentences(){while(1){sentence();if(match(";")){advance();if(match("}")){break; }else continue;}else{ERROR("前面没有';'");}}
}
void block(){if(match("{")){advance();if(match("}")){advance(); return;}sentences();if(!match("}"))ERROR("无'}'");else advance();}else ERROR("无'{'");
}
void process(){if(match("main")){advance();if(match("(")){advance();if(match(")")){advance();block();}else ERROR("无')'");}else ERROR("无'('");}else ERROR("无 main方法");
}
char finname[64],foutname[64],flogname[64];
int main(){cout<<"输入文件的路径:";cin>>finname;cout<<"输出的词法分析文件的路径:";cin>>foutname;cout<<"输出的语法分析文件的路径:";cin>>flogname;fin=fopen(finname,"r");fout=fopen(foutname,"w");v=analysis(fin,fout);fclose(fin);fclose(fout); flog=fopen(flogname,"w");process();fclose(flog);cout<<"accept!"<<endl;return 0;
}

5.总结

语法分析程序不是很完善,可以考虑在排查到错误后继续往后识别。

C语言词法分析和语法分析相关推荐

  1. SNL语言词法分析与语法分析程序-java

    程序运行截图: 源代码:链接:https://pan.baidu.com/s/13QzxEVy28m7MpmiUIrJykA 提取码:5hz3

  2. 编译原理实验报告一:PL0语言编译器分析(PL0,词法分析,语法分析,中间代码生成)

    实验报告一:PL0语言编译器分析 一.实验目的 通过阅读与解析一个实际编译器(PL/0语言编译器)的源代码, 加深对编译阶段(包括词法分析.语法分析.语义分析.中间代码生成等)和编译系统软件结构的理解 ...

  3. 使用C++对TINY+语言进行词法分析、语法分析、语义分析和中间代码生成

    实验报告 实验环境 操作系统:Win 10 编译器:g++ 项目地址 项目地址 实验目的 构造TINY+的语义分析程序并生成中间代码 实验内容 构造符号表,构造TINY+的语义分析器,构造TINY+的 ...

  4. 转:PL/0语言词法及语法分析系统的设计与实现

    PL/0语言词法及语法分析系统的设计与实现 作者:陶善文 南京航空航天大学信息与计算机科学专业 下载源代码 摘要:本文介绍了一个PL/0语言的词法及语法分析系统的设计与实现 关键词:循环分支 递归下降 ...

  5. 编译原理实验报告三:语法分析(PL0,词法分析,语法分析,中间代码生成)

    实验报告三:语法分析 一.实验目的 通过设计.开发一个S语言的语法分析程序,实现对源程序的语法检查和结构分析,加深对相关课堂教学内容的理解,提高语法分析方法的实践能力. 二.实验要求        根 ...

  6. C语言词法分析程序的设计与实现

    C语言词法分析程序 c++和lex两种实现 支持多种数字格式和转义字符 实现的功能 基本满足C语言的词法规则. 可以识别八进制,十六进制,浮点,科学计数法,同时支持后缀. 识别关键字. 识别字符和字符 ...

  7. 词法分析、语法分析、语义分析

    这里就是拿翻译句子来举例子,从英语翻译到汉语,我们需要分析句子的语义,要划分句子的成分 要想进行语义分析就要划分句子成分,比如说划分为人.铁锤.窗户等等 我们要想划分句子当中的各类成分,就要用语法分析 ...

  8. 小C语言–词法分析程序

    小C语言–词法分析程序 Time Limit: 1000 ms Memory Limit: 5000 KiB Problem Description 小C语言文法 1. <程序>→(){& ...

  9. 小C语言--词法分析程序

    小C语言--词法分析程序 Time Limit: 1000 ms Memory Limit: 65535 KiB Submit Statistic Problem Description 小C语言文法 ...

最新文章

  1. 高山仰止 | “利他主义者”乔治·普莱斯的一生(全文翻译自Independent)
  2. 市面上不成熟的系统Java_回顾java基础知识
  3. 计算机网掉了,非常急电脑掉网我电脑上上网就会自己掉网不显示网络断开但一切有关上 爱问知识人...
  4. liunx mysql模块_linux下安装MySQLdb模块_MySQL
  5. javascript   卸载事件(onunload)
  6. nodejs中的模块系统:exports导出模块
  7. Redis 常用操作命令,非常详细
  8. PHP 报错 Use of undefined constant prop_values - ass...
  9. Zookeeper 在Linux系统的安装
  10. Python项目实践:文本词频统计、软文的诗词风
  11. POJ1236:Network of Schools——题解
  12. oracle中 initcpa,oracle  11g rman备份
  13. Linux下Socket 函数集(四)
  14. C语言基础-01-指针
  15. python建模与仿真控制系统_控制系统的建模与仿真
  16. 万字拆解伊利:84天从0到千万GMV,传统巨头在抖音电商的“快与慢”
  17. 自定义java对象转换工具类
  18. Java图形化GUI界面
  19. 面试官:Redis如何实现持久化的、主从哨兵又是什么?
  20. 不吹不黑,思购甄选现在还能玩吗?

热门文章

  1. 基于WEB的论坛系统的设计与实现
  2. java递增序列号_生成Java自动递增序列号日食
  3. JAVA中String字符串删除指定字符的办法
  4. 输入字符串,删除指定的字符
  5. LAMP环境搭建与配置(二)
  6. LeetCode 1024 视频拼接
  7. python中finally的用法_python中的finally用法
  8. Android Bluetooth蓝牙enable过程
  9. Hacking Team不需越狱即可监控iOS用户
  10. openinstall免填邀请码的使用方式