编译原理语法分析 算术表达式

合集下载

编译原理-算术表达式赋值句数组元素的引用布尔表达式

编译原理-算术表达式赋值句数组元素的引用布尔表达式

10
一维数组元素的地址计算:
跳过前i-1个单元
addr(A[i]) = a + (i-1)*w
首首首
W首 首 首
二维数组元素的地址计算: addr(A[i1,i2])=a+((i1-1)*d2+(i2-1))*w
跳过前i2-1个单元
跳过前i1-1行
11
n维数组元素的地址计算 addr(A[i1,i2,...,in]) =a+((i1-1)*d2*d3*...*dn+(i2-1)*d3*d4*...*dn+...+ (in-1))*w =a-(d2*d3*...*dn+d3*d4*...*dn+...+dn+1)*w +(i1*d2*d3*...*dn+i2*d3*d4*...*dn+...+in-1*dn+in)*w =a–c*w+v*w 根据假设条件③w=1: addr(A[i1,i2,...,in])=a–c+v 其中: c = d2*d3*d4...*dn+d3*d4*d5...*dn+*d4*d5*d6...*dn...+dn+1 = (d2+1)*d3*...*dn+d4*d5...*dn+...+dn+1 =((d2+1)*d3+1)*d4*d5...*dn+...+dn+1 ...... = (...((d2+1)*d3+1)*d4...+1)*dn+1 同理: v = (...((i1*d2+i2)*d3+i3)*d4...+in-1)*dn+in

编译原理:算术表达式预测分析程序设计

编译原理:算术表达式预测分析程序设计

实验三:算术表达式预测分析程序设计LDi实验目的:(1)掌握自上而下语法分析的要求与特点。

(2)掌握LL(1)语法分析的基本原理和基本方法。

(3)掌握相应数据结构的设计方法。

2、实验内容:编程实现给定算术表达式的预测分析器。

算术表达式文法如下: E E+T | TT T*F | FF (E) | i3、设计说明:首先改写文法为LL(1)文法;构造LL(1)分析表,然后编写预测分析程序。

4、设计分析与步骤(1) 将原算术表达式方法改写为LL(1)文法为:E-->TE'E'-->+TE'| £T-->FT'T'-->*FT'| £F-->(E)|i(2) 计算文法中每一个非终结符的FIRST集和FOLLOW 集FIRST FOLLOWE { (,i } { #,) }E'{ +,& } { ),# }T { (,i } { ),+,# }T'{ *, & } { ),+,# }F { (,i } { * }(3 )构造预测分析表I ( ) + * #E E-- > TE' E-- >TE'E'E' -- > £E' -- > +TE' E' -- > £T T-- > FT'T-- >FT'T'T' -- > £T' -- > £T'- -> *FT'T' -- > £F F-- > i F-- > (E)(4 )程序设计用vector<char>定义的A和B分别作为分析栈和输入栈,用string类型的INPUT获取用户输入的原始字符串。

编译原理课程设计——算术表达式、for、while语句转换为四元式

编译原理课程设计——算术表达式、for、while语句转换为四元式

计算机与信息学院《操作系统与编译原理联合课程设计报告》专题:编译原理部分学生姓名:学号:专业班级:指导教师:2014 年 7 月一、设计目标设计一个语法制导翻译器,将算术表达式、for语句、while语句翻译成四元式。

要求先确定一个定义算术表达式、for语句、while语句的文法,为其设计一个语法分析程序,为每条产生式配备一个语义子程序,按照一遍扫描的语法制导翻译方法,实现翻译程序。

对用户输入的任意一个正确的表达式,程序将其转换成四元式输出。

二、设计思路开发平台:Visual C++ MFC解决这个问题的方案分为以下几个步骤:1.将算数表达式、for语句、while语句转换为四元式的第一步为对读入的表达式进行处理,即删除不必要的空格、回车、换行等,保证之后的步骤能够顺利进行。

2.分析算术表达式、for语句、while语句的文法。

3.通过词法分析判断语句中的每个字符的类型,如:数字、字母、符号等。

4.建立每种文法的LR(0)分析表,通过每个文法的LR(0)分析表对相应的表达式进行语法分析。

5.在语法分析正确的情况下,通过语法分析的中间过程的符号栈输出四元式,四元式的形式为:(op arg1 arg2 result)。

(一)算术表达式转换为四元式将算术表达式转换为四元式首先考虑了括号的问题,对于不同的算术表达式第一步进行词法分析,即确定各种符号的位置。

而括号中的式子是优先级最高的,应该最先进行处理。

我使用了一个数组记录算术表达式中括号的位置,并且定义了first_cc和first_jj函数对括号内的乘除法和加减法分别进行处理。

后将括号内的式子以四元式的形式输出。

通过以上转换,已将原算术表达式中的括号中的内容使用大写字母’A’、’B’……等代替(其中定义声明了change函数,用来将括号部分替换为大写字母)。

新的式子中,只含有加减乘除以及赋值这四种运算,后根据优先级的不同,逐步生成四元式。

其算法流程图如右图所示。

编译原理语义分析实验报告

编译原理语义分析实验报告

实验3 语义分析实验报告一、实验目的二、通过上机实习, 加深对语法制导翻译原理的理解, 掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。

三、实验要求四、采用递归下降语法制导翻译法, 对算术表达式、赋值语句进行语义分析并生成四元式序列。

五、算法思想1.设置语义过程。

(1)emit(char *result,char *ag1,char *op,char *ag2)该函数的功能是生成一个三地址语句送到四元式表中。

四元式表的结构如下:struct{ char result[8];char ag1[8];char op[8];char ag2[8];}quad[20];(2) char *newtemp()该函数回送一个新的临时变量名, 临时变量名产生的顺序为T1, T2, …char *newtemp(void){ char *p;char m[8];p=(char *)malloc(8);k++;itoa(k,m,10);strcpy(p+1,m);p[0]=’t’;return(p);}六、 2.函数lrparser 在原来语法分析的基础上插入相应的语义动作: 将输入串翻译成四元式序列。

在实验中我们只对表达式、赋值语句进行翻译。

源程序代码:#include<stdio.h>#include<string.h>#include<iostream.h>#include<stdlib.h>struct{char result[12];char ag1[12];char op[12];char ag2[12];}quad;char prog[80],token[12];char ch;int syn,p,m=0,n,sum=0,kk; //p是缓冲区prog的指针, m是token的指针char *rwtab[6]={"begin","if","then","while","do","end"};void scaner();char *factor(void);char *term(void);char *expression(void);int yucu();void emit(char *result,char *ag1,char *op,char *ag2);char *newtemp();int statement();int k=0;void emit(char *result,char *ag1,char *op,char *ag2){strcpy(quad.result,result);strcpy(quad.ag1,ag1);strcpy(quad.op,op);strcpy(quad.ag2,ag2);cout<<quad.result<<"="<<quad.ag1<<quad.op<<quad.ag2<<endl;}char *newtemp(){char *p;char m[12];p=(char *)malloc(12);k++;itoa(k,m,10);strcpy(p+1,m);p[0]='t';return (p);}void scaner(){for(n=0;n<8;n++) token[n]=NULL;ch=prog[p++];while(ch==' '){ch=prog[p];p++;}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){m=0;while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}else if((ch>='0'&&ch<='9')){{sum=0;while((ch>='0'&&ch<='9')){sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=11;if(sum>32767)syn=-1;}else switch(ch){case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>'){syn=21;token[m++]=ch;}else if(ch=='='){syn=22;token[m++]=ch;}else{syn=23;p--;}break;case'>':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=24;token[m++]=ch;}else{syn=20;p--;}break;case':':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=18;token[m++]=ch;}else{syn=17;p--;}break;case'*':syn=13;token[0]=ch;break; case'/':syn=14;token[0]=ch;break; case'+':syn=15;token[0]=ch;break; case'-':syn=16;token[0]=ch;break; case'=':syn=25;token[0]=ch;break; case';':syn=26;token[0]=ch;break; case'(':syn=27;token[0]=ch;break; case')':syn=28;token[0]=ch;break; case'#':syn=0;token[0]=ch;break; default: syn=-1;break;}}int lrparser(){//cout<<"调用lrparser"<<endl;int schain=0;kk=0;if(syn==1){scaner();schain=yucu();if(syn==6){scaner();if(syn==0 && (kk==0))cout<<"success!"<<endl;}else{if(kk!=1)cout<<"缺end!"<<endl;kk=1;}}else{cout<<"缺begin!"<<endl;kk=1;}return(schain);}int yucu(){// cout<<"调用yucu"<<endl;int schain=0;schain=statement();while(syn==26){scaner();schain=statement();}return(schain);}int statement(){//cout<<"调用statement"<<endl;char *eplace,*tt;eplace=(char *)malloc(12);tt=(char *)malloc(12);int schain=0;switch(syn){case 10:strcpy(tt,token);scaner();if(syn==18){scaner();strcpy(eplace,expression());emit(tt,eplace,"","");schain=0;}else{cout<<"缺少赋值符!"<<endl;kk=1;}return(schain);break;}return(schain);}char *expression(void){char *tp,*ep2,*eplace,*tt;tp=(char *)malloc(12);ep2=(char *)malloc(12);eplace=(char *)malloc(12);tt =(char *)malloc(12);strcpy(eplace,term ()); //调用term分析产生表达式计算的第一项eplacewhile((syn==15)||(syn==16)){if(syn==15)strcpy(tt,"+");else strcpy(tt,"-");scaner();strcpy(ep2,term()); //调用term分析产生表达式计算的第二项ep2strcpy(tp,newtemp()); //调用newtemp产生临时变量tp存储计算结果emit(tp,eplace,tt,ep2); //生成四元式送入四元式表strcpy(eplace,tp);}return(eplace);}char *term(void){// cout<<"调用term"<<endl;char *tp,*ep2,*eplace,*tt;tp=(char *)malloc(12);ep2=(char *)malloc(12);eplace=(char *)malloc(12);tt=(char *)malloc(12);strcpy(eplace,factor());while((syn==13)||(syn==14)){if(syn==13)strcpy(tt,"*");else strcpy(tt,"/");scaner();strcpy(ep2,factor()); //调用factor分析产生表达式计算的第二项ep2strcpy(tp,newtemp()); //调用newtemp产生临时变量tp存储计算结果emit(tp,eplace,tt,ep2); //生成四元式送入四元式表strcpy(eplace,tp);}return(eplace);}char *factor(void){char *fplace;fplace=(char *)malloc(12);strcpy(fplace,"");if(syn==10){strcpy(fplace,token); //将标识符token的值赋给fplacescaner();}else if(syn==11){itoa(sum,fplace,10);scaner();}else if(syn==27){scaner();fplace=expression(); //调用expression分析返回表达式的值if(syn==28)scaner();else{cout<<"缺)错误!"<<endl;kk=1;}}else{cout<<"缺(错误!"<<endl;kk=1;}return(fplace);}void main(){p=0;cout<<"**********语义分析程序**********"<<endl;cout<<"Please input string:"<<endl;do{cin.get(ch);prog[p++]=ch;}while(ch!='#');p=0;scaner();lrparser();}七、结果验证1、给定源程序begin a:=2+3*4; x:=(a+b)/c end#输出结果2、源程序begin a:=9; x:=2*3-1; b:=(a+x)/2 end#输出结果八、收获(体会)与建议通过此次实验, 让我了解到如何设计、编制并调试语义分析程序, 加深了对语法制导翻译原理的理解, 掌握了将语法分析所识别的语法成分变换为中间代码的语义翻译方法。

编译原理实验二LL(1)语法分析实验报告

编译原理实验二LL(1)语法分析实验报告

专题3_LL(1)语法分析设计原理与实现李若森 13281132 计科1301一、理论传授语法分析的设计方法和实现原理;LL(1) 分析表的构造;LL(1)分析过程;LL(1)分析器的构造。

二、目标任务实验项目实现LL(1)分析中控制程序(表驱动程序);完成以下描述算术表达式的 LL(1)文法的LL(1)分析程序。

G[E]:E→TE’E’→ATE’|εT→FT’T’→MFT’|εF→(E)|iA→+|-M→*|/设计说明终结符号i为用户定义的简单变量,即标识符的定义。

加减乘除即运算符。

设计要求(1)输入串应是词法分析的输出二元式序列,即某算术表达式“专题 1”的输出结果,输出为输入串是否为该文法定义的算术表达式的判断结果;(2)LL(1)分析程序应能发现输入串出错;(3)设计两个测试用例(尽可能完备,正确和出错),并给出测试结果。

任务分析重点解决LL(1)表的构造和LL(1)分析器的实现。

三、实现过程实现LL(1)分析器a)将#号放在输入串S的尾部b)S中字符顺序入栈c)反复执行c),任何时候按栈顶Xm和输入ai依据分析表,执行下述三个动作之一。

构造LL(1)分析表构造LL(1)分析表需要得到文法G[E]的FIRST集和FOLLOW集。

构造FIRST(α)构造FOLLOW(A)构造LL(1)分析表算法根据上述算法可得G[E]的LL(1)分析表,如表3-1所示:表3-1 LL(1)分析表主要数据结构pair<int, string>:用pair<int, string>来存储单个二元组。

该对照表由专题1定义。

map<string, int>:存储离散化后的终结符和非终结符。

vector<string>[][]:存储LL(1)分析表函数定义init:void init();功能:初始化LL(1)分析表,关键字及识别码对照表,离散化(非)终结符传入参数:(无)传出参数:(无)返回值:(无)Parse:bool Parse( const vector<PIS> &vec, int &ncol );功能:进行该行的语法分析传入参数:vec:该行二元式序列传出参数:emsg:出错信息epos:出错标识符首字符所在位置返回值:是否成功解析。

编译原理语法分析(1)

编译原理语法分析(1)

例如, 考虑句子 i+i*i 按文法G[E]的推导 最左推导: EE+Ei+Ei+E*E i+i*E i+i*i 最右推导: EE+EE+E*EE+E*i E+i*ii+i*i 注意: 推导过程不唯一, 通常只考虑最左 推导或最右推导。 最右推导又称为规范推导。 规范推导的逆过程称为规范归约。
+ 。 * 意味着或 = , 或 即1 n 1 n 1 n
例如,考虑算术表达式文法G[E]: E→E+E∣E*E∣(E)│i 非终结符E代表一类算术表达式, 从E出发可进行一系列推导, 表达式 i+i*i 的推导如下: E E+E E+E*E E+E*i E+i*i i+i*I 注意: 在每一步推 导中,只能对其中一个 非终结符用其对应的产生式右部的 一个候选式来替换。
文法可表示为 VN为非空非终结符集,且VT∩VN=Φ; (3) S为文法开始符, S∈VN; (4)ξ是产生式的非空有限集, 其中每个 产生式(规则)记作 → 或 ::= 左部∈(VT∪VN)+至少含一非终结符, 右部∈(VT∪VN)*。
B
3.1.3 正规式与上下文无关文法 1. 正规式到上下文无关文法的转换 由正规式构造CFG的一种方法: (1)构造正规式的NFA; (2)若0为初始状态, 则A0为开始符; (3)若存在映射关系f(i,a)=j, 则定义产生式Ai →aAj; (4)若存在映射关系f(i,ε)=j, 则定义产生式Ai →Aj; (5) 若i为终态, 则定义产生式Ai →ε。
产生式 (也称产生式规则或规则) 是 定义语法实体的一种书写规则。一个语 法实体的相关规则可能不止一个, 如: P→1, P→2 , P→n 相同左部的产生式可合并为一个: P→ 1| 2|„| n 其中, i(i=1,2,„,n)称为P的候选式。

编译原理词法分析和语法分析报告 代码(C语言版)

编译原理词法分析和语法分析报告 代码(C语言版)

词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。

(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。

空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2.2 各种单词符号对应的种别码:表2.1 各种单词符号对应的种别码单词符号种别码单词符号种别码bgin 1 :17If 2 := 18Then 3 < 20wile 4 <> 21do 5 <= 22end 6 > 23lettet(letter|digit)* 10 >= 24 dight dight* 11 = 25 + 13 ;26—14 ( 27* 15 ) 28/ 16 # 02.3 词法分析程序的功能:输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

3.1 主程序示意图:主程序示意图如图3-1所示。

编译原理课程设计_算术表达式的语法分析及语义分析程序设计(模版)

编译原理课程设计_算术表达式的语法分析及语义分析程序设计(模版)

编译原理课程设计_算术表达式的语法分析及语义分析程序设计(模版)第一篇:编译原理课程设计_算术表达式的语法分析及语义分析程序设计(模版)设计题一:算术表达式的语法分析及语义分析程序设计。

1.目的通过设计、编制、调试一个算术表达式的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。

2.设计内容及要求:算术表达式的文法:〈无符号整数〉∷=〈数字〉{〈数字〉} 〈标志符〉∷=〈字母〉{〈字母〉|〈数字〉} 〈表达式〉∷=[+|-]〈项〉{〈加法运算符〉〈项〉} 〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉} 〈因子〉∷=〈标志符〉|〈无符号整数〉|‘(’〈表达式〉‘)’ 〈加法运算符〉∷=+|-〈乘法运算符〉∷=*|/选择算符优先分析方法完成以上任务,生成逆波兰式的中间代码;(1)写出算术表达式的符合分析方法要求的文法,给出分析方法的思想,完成分析程序设计。

(2)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

源代码#define _CRT_SECURE_NO_WARNINGS #include “stdio.h” #include “stdlib.h” #include using namespace std;char data[20][20];//算符优先关系char s[100];//模拟符号栈s char lable[20];//文法终极符集char input[100];//文法输入符号串char str[20][10];//用于输入串的分析 int k,j;char a,q;int r;//文法规则个数int r1;int m, n, N;//转化后文法规则个数 char st[10][30];//用来存储文法规则char first[10][10];//文法非终结符FIRSTVT集char last[10][10];//文法非终结符LASTVT集int fflag[10] = { 0 };//标志第i个非终结符的FIRSTVT集是否已求出 int lflag[10] = { 0 };//标志第i个非终结符的LASTVT集是否已求出int deal();//对输入串的分析int terminal_symbol(char c);//判断字符c是否是终极符int location(char c);//求字符c在算符优先关系表中的下标void out(int j, int k, char *s);//打印s栈void firstvt(char c);//求非终结符c的FIRSTVT集void lastvt(char c);//求非终结符c的LASTVT集void table();//创建文法优先关系表 char output[10];//存储逆波兰式 void main(){ int i, j, k = 0;printf(“请输入文法规则数:”);scanf(“%d”, &r);printf(“请输入文法规则:n”);for(i = 0;i} for(i = 0;i} for(i = 0;ifor(j = 0;st[i][j]!= '';j++)if((st[i][j]'Z')&& st[i][j]!= '-'&&st[i][j]!= lable[k++] = st[i][j];for(j = 0;st[i][j]!= '';j++){ } if(st[i][0]'Z'){} if(st[i][j] >= 'A'&&st[i][j] <= 'Z'){} if(st[i][j + 1] >= 'A'&&st[i][j + 1] <= 'Z'){} printf(“文法error!n”);exit(-1);printf(“文法error!n”);exit(-1);scanf(“%s”, st[i]);//存储文法规则,初始化FIRSTVT集和LASTVT集*/first[i][0] = 0;/*first[i][0]和last[i][0]分别表示st[i][0]非终极符的last[i][0] = 0;FIRSTVT集和LASTVT集中元素的个数*/'>'&&st[i][j]!= '|')lable[k] = '#';lable[k + 1] = '';} table();//printf(“FIRST集为:n”);//输出每个非终结符的FIRST集for(i = 0;i} printf(“LAST集为:n”);//输出每个非终结符的LAST集for(i = 0;i} printf(“算符优先分析表如下:n”);for(i = 0;lable[i]!='';i++)printf(“t%c”, lable[i]);printf(“n”);for(i = 0;i} printf(“请输入文法输入符号串以#结束:”);scanf(“%s”, input);deal();cout << “逆波兰式为:”;for(i = 0;lable[i]!= '';i++)cout << output[i] << '';// cout << endl;printf(“%ct”, lable[i]);for(j = 0;jchar text[20][10];//存储改写后的文法int i, j, k, t, l, x = 0, y = 0;int m, n;x = 0;for(i = 0;ifirstvt(st[i][0]);lastvt(st[i][0]);} for(i = 0;i{text[x][y] = st[i][0];y++;for(j = 1;st[i][j]!= '';j++){if(st[i][j] == '|')//{text[x][y] = '';x++;y = 0;text[x][y] = st[i][0];y++;text[x][y++] = '-';text[x][y++] = '>';}else{text[x][y] = st[i][j];y++;}}text[x][y] = '';x++;y = 0;} r1 = x;//printf(“转化后的文法为:n”);for(i = 0;iprintf(“%sn”, text[i]);} for(i = 0;i{//输出转化后的文法规则串/*求每个终结符的推导结果(去掉“->”后的} str[i][0] = text[i][0];for(j = 3, l = 1;text[i][j]!= '';j++, l++)str[i][l] = text[i][j];str[i][l] = '';for(i = 0;ifor(j = 1;text[i][j + 1]!= '';j++){if(terminal_symbol(text[i][j])&& terminal_symbol(text[i][j + 1])){} if(text[i][j + 2]!= ''&&terminal_symbol(text[i][j])&& {} if(terminal_symbol(text[i][j])&&!terminal_symbol(text[i][j + 1]))//终结{} if(!terminal_symbol(text[i][j])&& terminal_symbol(text[i][j + 1]))//非终{ for(k = 0;k} m = location(text[i][j]);for(t = 0;t} n = location(first[k][t + 1]);data[m][n] = 'break;m = location(text[i][j]);n = location(text[i][j + 2]);data[m][n] = '=';m = location(text[i][j]);n = location(text[i][j +1]);data[m][n] = '=';terminal_symbol(text[i][j +2])&&!terminal_symbol(text[i][j + 1]))符和非终结符相接,用后于关系填表结符和终结符相接,用先于关系填表if(st[k][0] == text[i][j])break;}n = location(text[i][j + 1]);for(t = 0;t{m = location(last[k][t + 1]);data[m][n] = '>';}}} } m = location('#');//#后于所有的终结符规约for(t = 0;tn = location(first[0][t + 1]);data[m][n] = 'for(t = 0;tm = location(last[0][t + 1]);data[m][n] = '>';} data[n][n] = '=';}void firstvt(char c){ int i, j, k, m, n;for(i = 0;i {if(st[i][0] == c)break;} if(fflag[i] == 0){n = first[i][0] + 1;m = 0;do{if(m == 2 || st[i][m] == '|'){ if(terminal_symbol(st[i][m + 1]))//求FIRSTVT集}}} {} else {} if(terminal_symbol(st[i][m + 2])){} if(st[i][m + 1]!= c){firstvt(st[i][m + 1]);for(j = 0;j}for(k = 0;k}int t;for(t = 0;t}if(t == n){}first[i][n] = first[j][k + 1];n++;if(first[i][t] == first[j][k + 1])break;if(st[j][0] == st[i][m + 1])break;first[i][n] = st[i][m + 2];n++;first[i][n] = st[i][m + 1];n++;m++;} while(st[i][m]!= '');first[i][n] = '';first[i][0] =--n;fflag[i] = 1;void lastvt(char c)//求LASTVT集 {int i, j, k, m, n;for(i = 0;i} if(lflag[i] == 0){n = last[i][0] + 1;m = 0;do {if(st[i][m + 1] == '' || st[i][m + 1] == '|'){if(terminal_symbol(st[i][m])){} else {if(terminal_symbol(st[i][m1];n++;last[i][n] = st[i][m];n++;if(st[i][0] == c)break;}}}}}}if(t == n){}last[i][n] = last[j][k + 1];n++;m++;} while(st[i][m]!= '');last[i][n] = '';last[i][0] =--n;lflag[i] = 1;int deal(){int i, j;int size = 0;// int x, y;int z;//输入串的长度 k = 1;s[k] = '#';//栈置初值for(i = 0;input[i]!= '';i++);//计算输入串的长度z = i--;// i = 0;while((a = input[i])!= '')//a表示要输入的字符 {if(terminal_symbol(s[k]))j = k;j = k1]))j = j2;x = location(s[j]);y = location(q);} while(data[x][y]!= '} k = j + 1;if(k == 2 && a == '#'){out(1, k, s);printf(“%c”, a);out(i + 1, z, input);printf(“结束n”);for(N = 0;N} if(!terminal_symbol(s[m])&&!terminal_symbol(str[N][n])){} elseif(terminal_symbol(s[m]))if(s[m] == str[N][n]){}s[j + 1] = str[N][0];break;if(terminal_symbol(s[m + 1])&& terminal_symbol(str[N][n + 1]){}s[j + 1] = str[N][0];break;&& s[m + 1] == str[N][n + 1])}} printf(“规约成功!n”);return 1;//输入串符合文法的定义elseif(data[x][y] == 'out(1, k, s);printf(“%c”, a);out(i + 1, z, input);printf(“移进n”);k++;s[k] = a;i++;}else{printf(“n规约失败n”);return 0;} } printf(“n规约失败n”);//return 0;}void out(int j, int k, char *s){ int n = 0;int i;for(i = j;i <= k;i++){ printf(“%c”, s[i]);n++;} for(;n<15;n++){printf(“ ”);} }int location(char c){ int i;for(i = 0;lable[i]!= '';i++)//求字符c在算符优先关系表中的下标} {} return-1;if(c == lable[i])return i;int terminal_symbol(char c)//判断字符c是否是终极符 {} int i;for(i = 0;lable[i]!= '';i++){} return 0;if(c == lable[i])return 1;第二篇:编译原理语法分析实验报告实验2:语法分析1.实验题目和要求题目:语法分析程序的设计与实现。

编译原理课程设计--算术表达式的语法分析及语义分析程序设计 精品

编译原理课程设计--算术表达式的语法分析及语义分析程序设计 精品

课程设计任务书学生姓名:专业班级:指导教师:工作单位:题目: 算术表达式的语法分析及语义分析程序设计1.目的通过设计、编制、调试一个算术表达式的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。

2.设计内容及要求算术表达式的文法:(1)选择算符优先分析法完成以上任务,中间代码选用逆波兰式。

(2)写出算术表达式的符合分析方法要求的文法,给出分析方法的思想,完成分析程序设计。

(3)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

3.课程设计报告书的内容应包括:(1)设计题目、班级、学号、姓名、完成日期;(2)给出算术表达式的语法分析和语义分析的设计。

(3)简要的分析与概要设计;(4)详细的算法描述;(5)源程序清单;(6)给出软件的测试方法和测试结果;(7)设计的评价、收获与体会。

时间安排:第18周,周1-周3下午,周5全天指导教师签名:年月日系主任(或责任教师)签名:年月日1 课设要求设计题目算术表达式转换成逆波兰式(用算符优先分析法)1.1课程设计的目的课程设计是对学生的一种全面综合训练,是与课堂听讲、自学和练习相辅相成的必不可少的一个教学环节。

通常,设计题中的问题比平时的练习题要复杂,也更接近实际。

编译原理这门课程安排的课程设计的目的是旨在要求学生进一步巩固课堂上所学的理论知识,深化理解和灵活掌握教学内容,选择合适的数据逻辑结构表示问题,然后编制算法和程序完成设计要求,从而进一步培养学生独立思考问题、分析问题、解决实际问题的动手能力。

要求学生在上机前应认真做好各种准备工作,熟悉机器的操作系统和语言的集成环境,独立完成算法编制和程序代码的编写。

1.2 设计内容及要求算术表达式的文法:〈无符号整数〉∷=〈数字〉{〈数字〉}〈标志符〉∷=〈字母〉{〈字母〉|〈数字〉}〈表达式〉∷= [+|-]〈项〉{〈加法运算符〉〈项〉}〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}〈因子〉∷=〈标志符〉|〈无符号整数〉|‘(’〈表达式〉‘)’〈加法运算符〉∷=+|-〈乘法运算符〉∷=*|/1.选择算符优先分析法完成以上任务,中间代码选用逆波兰式。

c语言的编译原理

c语言的编译原理

c语言的编译原理
编译原理是指将高级语言(如C语言)编写的程序转换成机
器语言的过程。

它主要分为四个步骤:词法分析、语法分析、语义分析和代码生成。

词法分析是将源代码分解成一个个标记(token)的过程,每
个标记代表着一个词法单元,例如关键字、标识符、运算符等。

词法分析器会利用正则表达式等方法来识别源代码中的词法单元,并生成标记序列。

语法分析是将标记序列按照语法规则进行分析的过程。

它会将标记序列组织成一个由语法规则定义的语法树(Syntax Tree)。

语法分析器会利用文法规则和语法分析算法(如LL(k)算法、LR(k)算法等)来构建语法树。

语义分析是在构建语法树的基础上,对表达式、语句等进行语义检查和语义转换的过程。

语义分析器会检查类型匹配、作用域等语义规则,并将源代码转换成中间代码或目标代码。

代码生成是将中间代码或目标代码生成可执行文件的过程。

它包括了代码优化、目标机器指令的生成和链接等步骤。

代码生成器会根据目标机器的特性和约束,生成对应的机器指令,最终生成可执行文件。

总的来说,C语言的编译原理涉及了词法分析、语法分析、语
义分析和代码生成等几个关键步骤,通过这些步骤将C语言
程序转换成机器语言,从而使计算机能够理解和执行这些程序。

vvbhqw编译原理课程设计(语法分析程序)

vvbhqw编译原理课程设计(语法分析程序)

-+懒惰是很奇怪的东西,它使你以为那是安逸,是休息,是福气;但实际上它所给你的是无聊,是倦怠,是消沉;它剥夺你对前途的希望,割断你和别人之间的友情,使你心胸日渐狭窄,对人生也越来越怀疑。

—罗兰编译原理实验报告题目:对下面的文法对象,使用c语言构造它的预测分析程序;并任意给一算术表达式进行分析测试.分析对象对象定义如下:算术表达式→项|算术表达式+项|算术表达式-项项→因式|项*因式|项/因式因式→变量|(算术表达式)变量→字母字母→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实验日期:2005-6-15至2005-6-30指导教师:吴取劲班级:计算机029班学号:20029440913姓名:陈强一、分析语法分析部分我们我们采用ll(1)方法实现,采用ll(1)方法实现语法发分析要求文法满足以下要求:一个文法能否用确定的自顶向下分析与文法中相同左部的每个产生式右部的开始符号集合有关,当有右部能=*=>ε时则与其左部非终结符的后跟符号集合也有关,此外在产生式中不存在左递归即经过压缩,无左递归,无回溯。

它的基本思想是从左到右扫描源程序,同时从识别符号开始生成句子的最左推导,并只向前查看一个输入符号,便能唯一确定应选择的规则。

下面将确切地定义满足确定的自顶向下分析条件的文法即LL(1)文法及LL(1)文法的判别并介绍如何对非LL(1)文法进行等价变换问题,也就是消除一个文法中的左递归和左公共因子。

注意:一个文法中含有左递归和左公共因子绝对不是LL(1)文法,所以也就不可能用确定的自顶向下分析法,对此结论可以证明。

然而,某些含有左递归和左公共因子的文法在通过等价变换把它们消除以后可能变为LL(1)文法,但需要用LL(1)文法的定义判别,也就是说文法中不含左递归和左公共因子,只是LL(1)文法的必要条件。

LL(1) 文法的定义(5种定义):一个文法符号串的开始符号集合定义如下:定义 1.设G=(VT,VN,S,P)是上下文无关文法,α是任意的文法符号串,FIRST(α)是从α推导出的串的开始符号的终结符集合。

编译原理——表达式分析

编译原理——表达式分析

一、实验目的:熟悉并设计一个表达式的语法分析器二、相关知识:1、形式语言基础及其文法运算2、语法分析原理及4种常用的语法分析方法其中:四种算法为(1)设计算术表达式的递归下降子程序分析算法三、实验内容:1.设计表达式的语法语法分析器算法2.编写代码并上机调试运行通过要求:输入------------ 表达式输出------------ 表达式语法是否正确四、概要设计1.算术表达式的递归下降子程序分析算法(1)算术表达式文法G(E): E → E ω0 T | TT → T ω1 F | FF → i | (E)(2)文法变换:G’(E) E →T {ω0 T}T →F {ω1 F}F → i | (E)(3)递归下降子程序框图:E: 入口T:入口T Fn ω0? n ω1?y y出口出口read(w) read(w)T FF: 入口主程序:Z →E开始( ? n i ? n errread(w) read(w)EEerr n # ?err n ) ? yyread(w)结束出口(4)数据结构char exp[50]; //算术表达式区int i=0;int err=0 ; //err输出指示char w; //当前单词(5)源程序清单:#include <stdio.h>#include <stdlib.h>void E();void T();void F();int Print();char exp[50];//算术表达式区int i=0;int err=0;char w;//当前单词int Print(){printf("err") ;err=1;return err;}void F(){if((w>='a'&&w<='z')||(w>='0'&&w<='9')){w=exp[i++];//read(w)}else if(w=='('){w=exp[i++];E();if(w!=')'){if(!err)Print();}elsew=exp[i++];//read(w)}else{if(!err)Print();}}void T(){F();while(w=='*'||w=='/'){w=exp[i++];//read(w)F();}}void E(){T();while(w=='+'||w=='-'){w=exp[i++];//read(w)T();}}int main(){printf("please input your expression:");//输入表达式 scanf("%s",exp);w=exp[i++];//read(w)E();if(!err){if(w=='#')printf("OK!"); elseprintf("err"); }return 0;}(6)运行结果。

编译原理LL1语法分析算法的实现(token转四元式)

编译原理LL1语法分析算法的实现(token转四元式)

编译原理LL1语法分析算法的实现(token转四元式)编译原理LL1语法分析算法的实现(token转四元式)博客分类:•c++/数据结构/算法算法F#J##include <stdio.h>#include <stack>#include <vector>#include <iostream>#include <fstream>#include <malloc.h>using namespace std;//token结构struct token {int code; //token的类别,code为1则是符号,为2则是数字char value; //token的值};typedef struct token tokens;vector<tokens> tokenBuffer; //用于存储token的缓冲区stack<tokens> tokenBuffers;//产生式结构struct formula {int id; //产生式编号char left; //产生式左部char right[256]; //产生式右部int r_length; //产生式右部长度};typedef struct formula formulas;formulas formulaBuffer[11]; //用于存储产生式的缓冲区//四元式结构struct expression {char symbol; //操作符char num1; //第一个操作数char num2; //第二个操作数char result; //结果变量};typedef struct expression expressions;vector<expressions> expressionBuffer; //用于存储四元式的缓冲区int expressionCount = 0; //四元式个数//分析表中每一项的结构struct analysisTable {char currentState; //分析栈的栈顶符号char currentToken; //当前字符int expressionNum; //对应的产生式编号};typedef struct analysisTable analysisT ables;vector<analysisTables> analysisTableBuffer; //LL1分析表的缓冲区stack<char> analysisStack; //分析栈stack<char> sematicStack; //语义栈//初始化LL1分析表void initialAnalysisTableBuffer() { analysisTables* temp1a = new analysisTable; analysisTables* temp1b = new analysisTable; analysisTables* temp1c = new analysisTable; analysisTables* temp2 = new analysisTable; analysisTables* temp3 = new analysisTable; analysisTables* temp4 = new analysisTable; analysisTables* temp5 = new analysisTable; analysisTables* temp6 = new analysisTable; analysisTables* temp7a = new analysisTable; analysisTables* temp7b = new analysisTable; analysisTables* temp7c = new analysisTable; analysisTables* temp8 = new analysisTable; analysisTables* temp9 = new analysisTable; analysisTables* temp10 = new analysisTable; analysisTables* temp11 = new analysisTable; analysisTables* temp12 = new analysisTable; analysisTables* temp13 = new analysisTable; analysisTables* temp14 = new analysisTable; analysisTables* temp15a = new analysisTable; analysisTables* temp15b = new analysisTable; analysisTables* temp15c = new analysisTable; analysisTables* temp16 = new analysisTable;temp1a->expressionNum = 1;temp1a->currentState = 'E';temp1a->currentT oken = 'a';temp1b->expressionNum = 1; temp1b->currentState = 'E'; temp1b->currentT oken = 'b';temp1c->expressionNum = 1; temp1c->currentState = 'E'; temp1c->currentT oken = 'c';temp2->expressionNum = 1; temp2->currentState = 'E'; temp2->currentToken = '(';temp3->expressionNum = 2; temp3->currentState = 'L'; temp3->currentToken = '+';temp4->expressionNum = 3; temp4->currentState = 'L'; temp4->currentToken = '-';temp5->expressionNum = 4; temp5->currentState = 'L'; temp5->currentToken = ')';temp6->expressionNum = 4; temp6->currentState = 'L'; temp6->currentToken = '#';temp7a->expressionNum = 5;temp7a->currentT oken = 'a';temp7b->expressionNum = 5; temp7b->currentState = 'T'; temp7b->currentT oken = 'b';temp7c->expressionNum = 5; temp7c->currentState = 'T'; temp7c->currentT oken = 'c';temp8->expressionNum = 5; temp8->currentState = 'T'; temp8->currentToken = '(';temp9->expressionNum = 8; temp9->currentState = 'M'; temp9->currentToken = '+';temp10->expressionNum = 8; temp10->currentState = 'M'; temp10->currentT oken = '-';temp11->expressionNum = 6; temp11->currentState = 'M'; temp11->currentT oken = '*';temp12->expressionNum = 7;temp12->currentT oken = '/';temp13->expressionNum = 8;temp13->currentState = 'M';temp13->currentT oken = ')';temp14->expressionNum = 8;temp14->currentState = 'M';temp14->currentT oken = '#';temp15a->expressionNum = 9;temp15a->currentState = 'F';temp15a->currentToken = 'a';temp15b->expressionNum = 9;temp15b->currentState = 'F';temp15b->currentToken = 'b';temp15c->expressionNum = 9;temp15c->currentState = 'F';temp15c->currentToken = 'c';temp16->expressionNum = 10;temp16->currentState = 'F';temp16->currentT oken = '(';analysisTableBuffer.push_back(*temp1a); analysisTableBuffer.push_back(*temp1b); analysisTableBuffer.push_back(*temp1c);analysisTableBuffer.push_back(*temp2);analysisTableBuffer.push_back(*temp3);analysisTableBuffer.push_back(*temp4);analysisTableBuffer.push_back(*temp5);analysisTableBuffer.push_back(*temp6);analysisTableBuffer.push_back(*temp7a);analysisTableBuffer.push_back(*temp7b);analysisTableBuffer.push_back(*temp7c);analysisTableBuffer.push_back(*temp8);analysisTableBuffer.push_back(*temp9);analysisTableBuffer.push_back(*temp10);analysisTableBuffer.push_back(*temp11);analysisTableBuffer.push_back(*temp12);analysisTableBuffer.push_back(*temp13);analysisTableBuffer.push_back(*temp14);analysisTableBuffer.push_back(*temp15a);analysisTableBuffer.push_back(*temp15b);analysisTableBuffer.push_back(*temp15c);analysisTableBuffer.push_back(*temp16);}//由于本次实验主要是考察语法分析和语义分析,所以为了节省时间不采用查表的方式获取token,而是直接初始化token的值。

编译原理语法分析—自上而下分析

编译原理语法分析—自上而下分析

对文法G的任何符号串=X1X2…Xn构造集 合FIRST()。
1. 置FIRST()=FIRST(X1)\{};
2. 若对任何1ji-1,FIRST(Xj), 则把FIRST(Xi)\{}加至FIRST()中; 特别是,若所有的FIRST(Xj)均含有, 1jn,则把也加至FIRST()中。显 然,若=则FIRST()={}。
T→T*F | F
F→(E) | i
经消去直接左递归后变成:
E→TE E→+TE | T→FT T→*FT | F→(E) | i
(4.2)
例如文法G(S): S→Qc|c Q→Rb|b R→Sa|a
虽没有直接左递归,但S、Q、R都是左递归的
SQcRbcSabc
(4.3)
一个文法消除左递归的条件: 不含以为右部的产生式 不含回路。
即A的任何两个不同候选 i和 j FIRST(i)∩FIRST( j)=
当要求A匹配输入串时,A就能根据它所面临的第
一个输入符号a,准确地指派某一个候选前去执
行任务。这个候选就是那个终结首符集含a的。
提取公共左因子:
假定关于A的规则是 A→ 1 | 2 | …| n | 1 | 2 | … | m (其中,每个 不以开头)
*
特别是,若S A ,则规定
#FOLLOW(A)
构造不带回溯的自上而下分析的文法条件
1. 文法不含左递归,
2. 对于文法中每一个非终结符A的各个产生式 的候选首符集两两不相交。即,若
A→ 1| 2|…| n 则 FIRST( i)∩FIRST( j)= (ij)
3. 对文法中的每个非终结符A,若它存在某个 候选首符集包含,则
1)算符优先分析法:按照算符的优先关系和结 合性质进行语法分析。适合分析表达式。

编译原理第三章语法分析

编译原理第三章语法分析
void T() { F(); T’(); } void T’() { if(lookahead= =’*’) { match(‘*’); F(); T’(); } }
递归下降程序:
void F() { if(lookahead= =’i’) match(‘i’); else if(lookahead= =’(’) { match(‘(’); E(); if(lookahead= =’)’) match(‘)’); else error(); } else error(); }
输入串
id+id*id;# id+id*id;# id+id*id;# id+id*id;# id+id*id;# +id*id;# +id*id;#
动作
pop(L),push(E;L) pop(E),push(TE’) pop(T),push(FT’) pop(F),push(id) pop(id),next(ip) pop(T’)
形式语言分类
定义:若文法G=(N,T,P,S)的每个产生式α→β中,均有 α∈(N∪T)*N(N∪T)*,且至少含有一个非终结符, β∈(N∪T)*,则称G为0型文法(短语文法)。 ①1型文法(上下文有关文法):G的任何产生式α→β(S→ε 除外)均满足|α|≤| β| (|x|表示x中文法符号的个数); ②2型文法(上下文无关文法):G的任何产生式形如A→β, 其中A∈N,β∈(N∪T)*; ③3型文法(正规文法、线性文法):G的任何产生式形如A→a 或者A→aB(或者A→Ba),其中A,B∈N,a∈T*。
定义:将产生式A→γ的右部代替文法符号序列αAβ 中的A得到αγβ的过程,称为αAβ直接推导 出αγβ,记作:αAβαγβ。

编译原理中的词法分析与语法分析算法

编译原理中的词法分析与语法分析算法

编译原理中的词法分析与语法分析算法词法分析和语法分析是编译原理中的两个重要环节,用于将源代码转化为机器可识别的中间代码。

1.词法分析(Lexical Analysis):词法分析是将源代码的字符序列划分为一系列词素(Token)的过程。

词素是程序中具有独立意义的最小单位,如关键字、标识符、常量和运算符等。

词法分析器使用正则表达式或有限自动机等方法,从左至右扫描源代码,识别并输出词法单元序列。

常见的词法分析算法包括:-正则表达式匹配算法-有限自动机算法(如确定有限自动机和非确定有限自动机)2.语法分析(Syntax Analysis):语法分析是对词法单元序列进行语法分析,建立语法树或者语法分析树,以检查源代码是否符合编程语言的语法规则。

语法分析器使用上下文无关文法描述语言的语法规则,并采用不同的算法进行分析。

常见的语法分析算法包括:-递归下降分析算法- LR分析算法(如LR(0)、SLR、LR(1)、LALR等)- LL分析算法(如LL(1)等)- Earley分析算法补充拓展:除了词法分析和语法分析,编译原理中还涉及其他重要的编译器前端处理过程,如语义分析、中间代码生成等。

3.语义分析(Semantic Analysis):语义分析是在语法分析的基础上,对语法树或抽象语法树进行静态语义检查的过程。

在这一阶段,编译器会对语法结构进行语义规则的检查,如类型检查、变量声明检查等。

4.中间代码生成(Intermediate Code Generation):中间代码生成是在语义分析的基础上,将源代码转化为中间表示形式的过程。

中间代码是介于源代码和目标代码之间的一种中间形式,通常以一种抽象的形式表示程序的语义,便于后续优化和目标代码生成。

综上所述,词法分析和语法分析是编译原理中的两个基础环节,其算法有多种实现方式,而语义分析和中间代码生成则是编译器前端的进一步处理过程。

在实际的编译器实现中,这些处理过程通常会相互协作,以完成源代码的转化过程。

北邮编译原理实验 LR语法分析 实验报告

北邮编译原理实验  LR语法分析 实验报告

LR语法分析实验报告班级:2010211308 姓名:杨娜学号:10211369一.题目:LR语法分析程序的设计与实现二.设计目的:(1)了解语法分析器的生成工具和编译器的设计。

(2)了解自上而下语法分析器的构造过程。

(3). 理解和掌握LR语法分析方法的基本原理;根据给出的LR)文法,掌握LR分析表的构造及分析过程的实现。

(4)掌握预测分析程序如何使用分析表和栈联合控制实现LR分析。

三.实验内容:编写语法分析程序,实现对算术表达式的语法分析,要求所分析算数表达式由如下的文法产生:E->E+T|E-T|TT->T/F|T*F|FF->i|n|(E)四.实验要求:编写LR语法分析程序,要求如下:(1)构造识别所有活动的DFA(2)构造LR分析表(3)编程实现算法4.3,构造LR分析程序五.算法流程分析程序可分为如下几步:六.算法设计1.数据结构s :文法开始符号line :产生式的个数G[i][0] :产生式的标号Vt[] :终结符Vn[] :非终结符id :项目集编号Prjt *next :指示下一个项目集Prjt[]:存储项目的编号,prjt[0]项目编号的个数Pointafter[] :圆点后的字符,pointafter[0]为字符个数Prjset*actorgo[]:存储出度Pointbefore:圆点前面的字符Form:动态数组下标,同时作为符号的编号Vn[] :非终结符序列Vt[]:终结符序列2.LR分析器由三个部分组成(1)总控程序,也可以称为驱动程序。

对所有的LR分析器总控程序都是相同的。

(2)分析表或分析函数,不同的文法分析表将不同,同一个文法采用的LR分析器不同时,分析表将不同,分析表又可以分为动作表(ACTION)和状态转换(GOTO)表两个部分,它们都可用二维数组表示。

(3)分析栈,包括文法符号栈和相应的状态栈,它们均是先进后出栈。

分析器的动作就是由栈顶状态和当前输入符号所决定。

(完整)编译原理实验报告(词法分析器 语法分析器)

(完整)编译原理实验报告(词法分析器 语法分析器)

编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字。

标示符。

无符号整数.运算符.和界符。

三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号.2、程序流程图(1)主程序(2)扫描子程序3、各种单词符号对应的种别码五、实验内容:1、实验分析编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k(int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符.字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。

2 实验词法分析器源程序:#include 〈stdio.h〉#include <math.h>#include <string。

h>int i,j,k;char c,s,a[20],token[20]={’0’};int letter(char s){if((s〉=97)&&(s〈=122)) return(1);else return(0);}int digit(char s){if((s〉=48)&&(s<=57)) return(1);else return(0);}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else”)==0) return(3);else if(strcmp(token,"switch”)==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf(”please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!=’#’);i=1;j=0;get();while(s!=’#'){ memset(token,0,20);switch(s){case 'a':case ’b':case ’c':case ’d':case ’e’:case ’f’:case 'g’:case ’h':case 'i':case ’j':case 'k’:case ’l':case 'm’:case 'n':case ’o':case ’p':case ’q’:case 'r’:case 's’:case 't’:case ’u’:case ’v’:case ’w’:case ’x':case ’y':case ’z’:while(letter(s)||digit(s)){token[j]=s;j=j+1;get();}retract();k=lookup(token);if(k==0)printf("(%d,%s)”,6,token);else printf("(%d,—)",k);break;case ’0':case ’1’:case ’2':case ’3':case '4’:case '5’:case ’6':case ’7’:case ’8’:case '9’:while(digit(s)){token[j]=s;j=j+1;get();}retract();printf(”%d,%s",7,token);break;case '+':printf(”(’+',NULL)”);break;case ’-':printf("(’-',null)");break;case ’*':printf(”('*’,null)");break;case '<':get();if(s=='=’) printf(”(relop,LE)”);else{retract();printf("(relop,LT)");}break;case ’=':get();if(s=='=’)printf("(relop,EQ)");else{retract();printf(”('=',null)”);}break;case ’;':printf(”(;,null)");break;case ' ’:break;default:printf("!\n”);}j=0;get();} }六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术.三、实验原理:1、算术表达式语法分析程序的算法思想首先通过关系图法构造出终结符间的左右优先函数f(a),g(a)。

编译原理语法分析算术表达式 (1)

编译原理语法分析算术表达式 (1)

package语法分析;public class displymain {public static void main(String args[]) {new frame();}}package 语法分析;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.*;public class frame implements ActionListener{JFrame frame1;JLabel L1,L2;JButton bt,bt2;JTextField input,result;top_down_grammar a =new top_down_grammar();public frame(){frame1=new JFrame("");input=new JTextField(20);result=new JTextField(20);L1=new JLabel("请输入表达式以#结束");L2=new JLabel("结果是:");bt=new JButton("语法分析");bt2=new JButton("关闭");frame1.setTitle("递归下降子程序分析语法");frame1.setLayout(new GridLayout(3,1));frame1.add(L1);frame1.add(input);frame1.add(L2);frame1.add(result);frame1.add(bt);frame1.add(bt2);bt.addActionListener(this);bt2.addActionListener(this);frame1.setSize(500, 500);frame1.setVisible(true);}public void actionPerformed(ActionEvent e){a.i=0;a.x.str=input.getText();if(e.getActionCommand()=="语法分析"){if(a.E_Production()) result.setText("符合语法要求");else result.setText("不符合语法要求");}if(e.getActionCommand()=="关闭"){frame1.dispose();}}}package 语法分析;public class Lex{String str="";int i;//int j=0;public char lex(int j){ i=j;if(is_identifiers_key()){return '2';}if(is_digital())return '1';if(is_oper())return str.charAt(i);return '0';}public boolean is_identifiers_key(){boolean f=false;//c2=str.charAt(i);while((i<str.length()&&((str.charAt(i)>=65&&str.charAt(i)<=90)||(str.charAt(i)>=97&&str.charA t(i)<=122)||(str.charAt(i)=='_')))){i++;f=true;}if(f)i--;return f;}public boolean is_digital(){ boolean f=false;if(i<str.length()&&str.charAt(i)>=48&&str.charAt(i)<=57){while(((str.charAt(i)>=48&&str.charAt(i)<=57)||str.charAt(i)=='.')){i++;f=true;}//c=(str.charAt(i));if(f)i--;return f;}return false;}public boolean is_oper(){ // c2=str.charAt(i);if(i<str.length())if(str.charAt(i)=='('||str.charAt(i)==')'||str.charAt(i)=='+'||str.charAt(i)=='-'||str.charAt(i)=='*'||str.charAt(i)=='/'||str.charAt(i)=='#'){return true;}return false;}}package语法分析;public class top_down_grammar {char ch;int i=0;Lex x=new Lex();public boolean E_Production(){ch=x.lex(i);if(ch=='+' ||ch=='-') { i=x.i;i++;ch=x.lex(i);}if(!T_Production()) return false;if(!G_Production()) return false;return true; }public boolean T_Production(){if( !F_Production()) return false;if(!S_Production()) return false;return true;}public boolean F_Production(){if(ch=='('){ i=x.i;i++;ch=x.lex(i);if(E_Production())return false;if(ch==')'){i=x.i;i++;ch=x.lex(i);return true;}else return false;}if(ch=='1'||ch=='2'){i=x.i;i++;ch=x.lex(i);return true;}else return false;}public boolean G_Production(){if(ch=='+'){i=x.i;i++;ch=x.lex(i);if(!T_Production()) return false;if(!G_Production()) return false;return true;}else if(ch=='-'){i=x.i;i++;ch=x.lex(i);if(!T_Production()) return false;if(G_Production()) return false;return true;}else if(ch==')'||ch=='#'){return true;}return false;}public boolean S_Production(){if(ch=='*'){i=x.i;i++;ch=x.lex(i);if(!F_Production()) return false;if(!S_Production()) return false;return true;}else if(ch=='/'){i=x.i;i++;ch=x.lex(i);if(!F_Production()) return false;if(!S_Production()) return false;return true;}else if(ch=='+'||ch=='-'||ch=='#'||ch==')') { if(i<x.str.length()&&ch!='#'){if(x.str.charAt(i+1)!='#')return true;else return false;}return true;}return false;}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
i++;
f=true;
}
//c=(str.charAt(i));
if(f)
i--;
return f;
}
return false;
}
public boolean is_oper()
{ // c2=str.charAt(i);
if(i<str.length())
if(str.charAt(i)=='('||str.charAt(i)==')'||str.charAt(i)=='+'||str.charAt(i)=='-'||str.charAt(i)=='*'||str.charAt(i)=='/'||str.charAt(i)=='#')
{
boolean f=false;
//c2=str.charAt(i);
while((i<str.length()&&((str.charAt(i)>=65&&str.charAt(i)<=90)||(str.charAt(i)>=97&&str.charAt(i)<=122)||(str.charAt(i)=='_'))))
{
i=x.i;
i++;
ch=x.lex(i);
if(!T_Production())returnfalse;
if(!G_Production())returnfalse;
returntrue;
}
elseif(ch=='-')
{
i=x.i;
i++;
ch=x.lex(i);
if(!T_Production())returnfalse;
frame1.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
a.i=0;
a.x.str=input.getText();
if(e.getActionCommand()=="语法分析")
{
if(a.E_Production()) result.setText("符合语法要求");
frame1.add(input);
frame1.add(L2);
frame1.add(result);
frame1.add(bt);
frame1.add(bt2);
bt.addActionListener(this);
bt2.addActionListener(this);
frame1.setSize(500, 500);
{
return true;
}
return false;
}
}
package语法分析;
publicclasstop_down_grammar {
charch;
inti=0;
Lexx=newLex();
publicbooleanE_Production()
{
ch=x.lex(i);
if(ch=='+'||ch=='-')
}
returnfalse;
}
}
returntrue;
}
elseif(ch=='+'||ch=='-'||ch=='#'||ch==')')
{if(i<x.str.length()&&ch!='#')
{
if(x.str.charAt(i+1)!='#')
returntrue;
elsereturnfalse;
}
returntrue;
top_down_grammar a =new top_down_grammar();
public frame()
{
frame1=new JFrame("");
input=new JTextField(20);
result=new JTextField(20);
L1=new JLabel("请输入表达式以#结束");
if(!F_Production())returnfalse;
if(!S_Production())returnfalse;
returntrue;
}
elseif(ch=='/')
{
i=x.i;
i++;
ch=x.lex(i);
if(!F_Production())returnfalse;
if(!S_Production())returnfalse;
else result.setText("不符合语法要求");
}
if(e.getActionCommand()=="关闭")
{
frame1.dispose();
}
}
}
package语法分析;
public class Lex
{
String str="";
int i;
//int j=0;
public char lex(int j)
if(!S_Production())returnfalse;
returntrue;
}
publicbooleanF_Production()
{
if(ch=='(')
{i=x.i;
i++;
ch=x.lex(i);
if(E_Production())
returnfalse;
if(ch==')')
{
i=x.i;
{ i=j;
if(is_identifiers_key())
{
return '2';
}
if(is_digital())
return '1';
if(is_oper())
return str.charAt(i);
return '0';
}
public boolean is_identifiers_key()
if(G_Production())returnfalse;
returntrue;
}
elseif(ch==')'||ch=='#')
{
returntrue;
}
returnfalse;
}
publicbooleanS_Production()
{
if(ch=='*')
{
i=x.i;
i++;
ch=x.lex(i);
i++;
ch=x.lex(i);
returntrue;
}
elsereturnfalse;
}
if(ch=='1'||ch=='2')
{
i=x.i;
i++;
ch=x.lex(i);
returntrue;
}
elsereturnfalse;
}
publicbooleanG_Production()
{
if(ch=='+')
import java.awt.event.ActionListener;
import javax.swing.*;
public class frame implements ActionListener{
JFrame frame1;
JLabel L1,L2;
JButton bt,bt2;
JTextField input,result;
{
i++;
f=true;
}
if(f)
i--;
return f;
}
public boolean is_digital()
{ boolean f=false;
if(i<str.length()&&str.charAt(i)>=48&&str.charAt(i)<=57)
{
while(((str.charAt(i)>=48&&str.charAt(i)<=57)||str.charAt(i)=='.'))
L2=new JLabel("结果是:");
bt=new JButton("语法分析");
bt2=new JButton("关闭");
frame1.setTitle("递归下降子程序分析语法");
frame1.setLayout(new GridLayout(3,1));
frame1.add(L1);
package语法分析;
publicclassdisplymain {
publicstaticvoidmain(String args[])
{
newframe();
}
}
package语法分析;
import java.awt.GridLayout;
import java;
相关文档
最新文档