语法分析实验部分简易版
来源:互联网 发布:5g网络架构 杨峰义pdf 编辑:程序博客网 时间:2024/06/05 22:58
代码是从清华那本编译教材后边实验部分改的
二、实验内容
“简单的算法表达式文法”
〈算术表达式〉∷=〈项〉│〈算术表达式〉+〈项〉│〈算术表达式〉-〈项〉
〈项〉∷=〈因式〉│〈项〉*〈因式〉│〈项〉/〈因式〉
〈因式〉∷=〈变量〉│(〈算术表达式〉)
〈变量〉∷=a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z
说明:为了简化变量,即简化词法分析程序,此文法中变量的定义就是一个字母。
根据“简单的算法表达式文法”在starter files基础上编写一个递归向下的语法分析程序。
输入:字符串或者文本文件
输出:“合法表达式”或者“非法表达式”
例如:输入a+b*c-b/d则显示或者输出“合法表达式”,输入aa++–c*则显示或者输出“非法表达式”
三、实验分析与设计
S: 算术表达式
B: 项
C: 因式
D: 变量
消除左递归后的文法:
S->BI
I->+BI|-BI|ξ
B->CJ
J->*BI|/BI|ξ
C->D|(S)
D->a|…|z
First(S)={a,…,z,(}
First(I)={+,-, ξ}
First(B)={a,…,z,(}
First(J)={*,/, ξ}
First(C)={a,…,z,(}
First(D)={a,…,z}
Follow(S)={#,)}
Follow(B)={+,-,),#}
Follow(I)={#,)}
Follow(J)={+,-,),#}
Follow(C)={*,/,+,-,),#}
Follow(D)={*,/,+,-,),#}
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>/* 符号 */enum symbol //枚举类型{ nul, end, ident, plus, times, lparen, divide, rparen, sub,};#define al 10 //标识符的最大长度enum symbol sym; //当前的符号char ch; //获取当前字符,getch 使用char a[al+1]; //当前标识符identFILE* fin; //用于指向输入文件的指针void getsym(); //读单词,将单词类别放入sym中void S();void I();void B();void J();void C();void D();int main(){ char filename[20]; //文件名数组 printf("请输入分析的文件名:"); gets(filename); //scanf("%s",filename); do { if((fin=fopen(filename,"r"))==NULL) //以只读方式打开文件,并判断输入文件名是否正确 { printf("不能打开文件.\n"); return 0; } getsym(); //读第一个单词,将单词类别放入sym中 S(); //开始按E->TA 分析 if (sym==end) { printf("语法正确\n"); } else { printf("语法错\n"); } fclose(fin); //关闭文件 printf("继续分析则输入文件名,否则回车"); //scanf("%s",filename); gets(filename); } while (strlen(filename)>0); //判断文件名字符串是否大于0}/*词法分析,获取一个符号*/void getsym(){ ch=fgetc(fin); while (ch==' ' || ch==10 || ch==13 || ch==9) /* 忽略空格、换行、回车和TAB */ ch=fgetc(fin); if (ch==EOF) sym=end; else if (ch>='a' && ch<='z') sym = ident; else if(ch == '+') sym = plus; else if (ch == '*') sym = times; else if (ch == '/') sym = divide; else if (ch == '-') sym = sub; else if (ch == '(') sym = lparen; else if (ch == ')') sym = rparen; else { sym = nul; printf("--词法错\n"); exit(0); } return;}//递归下降分析 分析产生式E-> TAvoid S(){ if (sym==ident ||sym==lparen) //如果类型是标识符(变量)或者左括号 { B(); //先按B推导,执行B I(); //再按I推导,执行I } else { printf("语法错: 缺变量或者左括号\n"); exit(0); }}void D(){ if (sym==ident) //当前单词为indent(标识符)类型 getsym(); //读下一个单词 else { printf("语法错: 缺变量\n "); exit(0); }}//添加void I(){ if(sym==plus||sym==sub) //如果类型是加或者减 { getsym(); //读下一个单词 B(); //调用执行B I(); //调用执行I } else if(sym==rparen || sym==end)//右括号或者文件结束 { return; } else { if(sym==nul) { printf("错误4:非法操作符\n"); exit(0); } else { printf("错误5:缺少操作符+或者缺少操作符-"); exit(0); } }}void B(){ C(); //调用执行C J(); //调用执行J}void J(){ if(sym==times||sym==divide) //如果类型是*或者除法 { getsym(); //读取下一个单词 C(); //调用执行C J(); //调用执行J } else if(sym==plus || sym==sub || sym==rparen || sym==end)//+——)或者结束 { return; } else { if(sym==nul) { printf("错误4:非法操作符\n"); exit(0); } else { printf("错误6:缺少操作符×或者÷\n"); exit(0); } }}void C(){ if(sym==lparen) //如果类型是左括号 { getsym(); //读取下一个单词 S(); //调用执行S if(sym==rparen) //如果类型是右括号 { getsym(); //读取下一个单词 return; } else { printf("语法错: 缺变量或符号\n "); exit(0); } } else { D(); //否则调用执行D }}
五、运行的结果
懒得贴的还要截图 反正可以正经运行
- 语法分析实验部分简易版
- 递归下降语法分析实验
- 递归下降语法分析实验
- Makefile 语法分析 第三部分
- LL(1)语法分析实验报告
- 编译原理 实验3 语法分析
- 实验三:CMM语言语法分析
- Java 课本实验 华容道(简易版)
- 编译原理语法分析实验(Java实现)
- 语法分析-哈工大编译原理实验二
- PL0语法分析程序(表达式部分)
- Shell解释器(含部分语法分析)
- 语法分析
- 语法分析
- 语法分析
- 语法分析
- 语法分析
- 语法分析
- Saving HDU||HDU2111
- hdu 5877(树状数组+离散化)
- HDU 5889 Barricade 最小割
- unity 垃圾回收性能分析
- java初级面试题,java中常见的类,包,接口
- 语法分析实验部分简易版
- 2017.8.11
- 字母x在css中的角色
- 8.11
- 2017/8/11
- Refletion2017.8.11
- 字体图标
- 二叉树的前序,中序,后序遍历。用递归和非递归实现
- HDO 5748 Bellovin