您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页编译原理实验LL1分析法综述

编译原理实验LL1分析法综述

来源:化拓教育网
编译原理程序设计实验报告

——表达式语法分析器的设计实现

班级:计算机1306班 姓名:王利达

学号:20133959

实验目标:使用LL(1)分析法构造表达式语法分析器程序,判别算术表达式,给出判别结果。

实验内容: 一、概要设计

1.算术表达式文法:

E→ T | Eω0T T→ F | Tω1F F→ i | ( E ) 其中ω0:+ - ω1:* / i:数字或常数 文法变换: E → T M M → ω0 T M |ε T → F | N N → ω1 F N |ε

F → i | ( E ) 其中ω0:+ - ω1:* / i:数字或常数 2.LL(1)分析表

表1.LL(1)分析表 E M T N F ) # i MT,p NF,p ε,n + MT,n - MT,n * NF,n / NF,n ( MT,p NF,p )E,n ) ε,p ε,p ε,n # ε,p ε,p OK

二、数据结构

1.输入表达式

定义char型数组expstr为存放输入表达式的数组,

char expstr[100];

2.分析栈

定义一个栈来进行LL(1)分析。栈中有bottom、top、stacksize等元素,用于程序调用栈和对栈操作。

typedef struct //定义语法的栈 {

SElemType *bottom;//底 SElemType *top;//顶 int stacksize; }SqStack;

(包括:概要设计、数据结构、流程图、关键函数等 有选择填写)

源程序代码:(加入注释)

#include #include #include

using namespace std;

#define STACKSIZE 30 //栈大小 #define STACKINCREMENT 10 //栈增量 #define OK 1 #define Error 0

#define OVERFLOW -1

typedef char SElemType; typedef int Status;

int i=0;

int count1=0;

int count2=0; //计数终结符的个数 char expstr[100];

typedef struct //定义语法的栈 {

SElemType *bottom;//底 SElemType *top;//顶 int stacksize; }SqStack;

Status InitStack(SqStack &S) //初始化栈 {

S.bottom=(SElemType*)malloc(STACKSIZE*sizeof(SElemType)); if(!S.bottom)

exit(OVERFLOW); S.top=S.bottom;

S.stacksize=STACKSIZE;

return OK; }

Status PUSH(SqStack &S,SElemType e) {

if(S.top-S.bottom>=S.stacksize) {

S.bottom=(SElemType*)realloc(S.bottom,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));

if(!S.bottom)

exit(OVERFLOW); S.top=S.bottom+S.stacksize;

S.stacksize+=STACKINCREMENT; }

*(S.top)=e; (S.top)++; return OK; }

Status POP(SqStack &S,SElemType &e) {

if(S.top==S.bottom) return Error; S.top--; e=*(S.top); return OK; }

void wrong()//调用此函数,表示出错 {

cout<<\"Wrong!\"<bool ch_judge(char s[],int n) //字符是否合法 {

if((s[n]=='(')||(s[n]==')')||(s[n]>='0'&&s[n]<='9')||(s[n]>='a'&&s[n]<='z')||(s[n]=='+')||(s[n]=='-')||(s[n]=='*')||(s[n]=='/')||(s[n]=='#')) return 1; else

return 0; }

bool ter_judge(char c) //终结符集合与非终结符集合 {

if((c=='(')||(c==')')||(c>='0'&&c<='9')||(c>='a'&&c<='z')||(c=='+')||(c=='-')||(c=='*')||(c=='/')) return 1; //终结符 返回1

else //if(c=='E'||c=='E1'||c=='T'||c=='T1'||c=='F') return 0; //非终结符或#,返回0 }

bool num_letter(char s[],int i) //判断当前字符是数字还是字母 {

if((s[i]>='0'&&s[i]<='9')||(s[i]>='a'&&s[i]<='z')) {

i++;

while((s[i]>='0'&&s[i]<='9')||(s[i]>='a'&&s[i]<='z')) {

i++;

count1++; }

while(count1!=0) {

i--;

count1--; } i--;

return 1; //是字母或数字返回1 } else

return 0; //不是字母或数字返回0 }

void LL1(SqStack &S,char s[],int i)//LL1文法分析函数 {

SElemType e; PUSH(S,'#'); PUSH(S,'E'); while(s[i]!='#') {

if(ch_judge(s,i)) {

POP(S,e);

if(!(ter_judge(e))) //是非终结符 {

if(e=='#'&&s[i]=='#')

break; //表达式正确 else if(e=='#'&&s[i]!='#') wrong();

else if(e!='#') //分析表匹配 {

switch(e) {

case 'E':

if(num_letter(s,i)||s[i]=='(') {

e='M'; // E' M PUSH(S,e); e='T';

PUSH(S,e); break; } else

wrong(); case 'M':

if(s[i]=='+'||s[i]=='-') {

e='M'; PUSH(S,e); e='T';

PUSH(S,e); e=s[i];

PUSH(S,e); break; }

else if(s[i]==')'||s[i]=='#') {

break; } else

wrong(); case 'T':

if(num_letter(s,i)||s[i]=='(') {

e='N'; //T' N PUSH(S,e); e='F';

PUSH(S,e); break; }

else

wrong(); case 'N':

if(s[i]=='+'||s[i]=='-'||s[i]==')'||s[i]=='#') {

break; }

else if(s[i]=='*'||s[i]=='/') {

的终结符压栈

e='N';

PUSH(S,e); e='F';

PUSH(S,e); e=s[i];

PUSH(S,e); break; } else

wrong(); case 'F':

if(num_letter(s,i)) {

while((s[i]>='0'&&s[i]<='9')||(s[i]>='a'&&s[i]<='z')) //将连续 {

e=s[i];

PUSH(S,e); i++;

count2++; //给连续终结符计数 }

i--; //使s[i]为连续终结符即一个整数的最后一字 break; }

else if(s[i]=='(') {

e=')';

PUSH(S,e); e='E';

PUSH(S,e); e='(';

PUSH(S,e); break; } else

wrong(); default:

wrong(); } } } else {

if((s[i]>='0'&&s[i]<='9')||(s[i]>='a'&&s[i]<='z'))//如果是数字或字母则依次计数

{

while(ter_judge(e)) {

if(e==s[i]) {

i--;

POP(S,e); } else

wrong(); }

while(count2!=0) {

i++; count2--; }

PUSH(S,e); i++; }

else //如果是+-*/则直接比较 {

if(e==s[i]) i++; else

wrong(); } } } else

wrong(); } }

int main()

{

SqStack S; InitStack(S);

cout<<\"LL(1)\\nPlease enter the expression and end with the \\\"#\\\":\"<>expstr; LL1(S,expstr,i);

cout<<\"Right! \"<程序运行结果:(截屏)

图1.正确的算术表达式(((a+b)*(c/B)))的判断

图2.错误的算术表达式a/b++的判断

思考问题回答:(如果有)

LL(1)分析法和递归下降子程序法在语法分析中同属于自顶向下分析法,LL(1)分析法相对于递归下降子程序法的优势是:LL(1)分析法消除了文法的左递归性,而且克服了回溯,使程序运行的效率大大提升。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务