精华内容
下载资源
问答
  • 递归下降语法分析器
    2021-05-20 16:53:31

    递归下降语法分析器实验报告

    编译原理实验报告

    题目: 递归下降语法分析器

    学 院 计算机科学与技术

    专 业 xxxxxxxxxxxxxxxx

    学 号 xxxxxxxxxxxx

    姓 名 宁剑

    指导教师 xx

    20xx年xx月xx日

    递归下降语法分析器

    一、实验目的?

    ???? 了解语法分析的内部工作原理,通过在本次实验中运用一定的编程技巧,掌握对表达式进行处理的一种方法。

    算术表达式的文法可以是可以根据需要适当改变:

    →E+E|E-E|E*E|E/E|(E)|i

    ??? ?根据递归下降分析法或预测分析法 ,对表达式进行语法分析 ,判断一个表达式是否正确 。

    (1) 准备:1. 阅读课本有关章节,确定算术表达式的文法(设计出预测分析表2. 考虑好设计方案;3. 设计出模块结构 、测试数据,初步编制好程序。

    (2) 上机调试,发现错误,分析错误,再修改完善。教师根据学生的设计方案与学生进行探讨,以修改方案和代码 。

    (3)改造后的文法:E→E+T|E-T|T

    T→TF|T/F|F

    F→F^|P

    P→c |id| (E)

    四、实验环境?

    计算机 VC++软件#include

    #include

    #include

    #include

    #include

    void error();

    void terror();

    void Scanner();

    char sym=' ';

    int i=0;

    char strToken[30]={""};

    FILE *in;

    void E();

    void E1();

    void F();

    void Retract(char str[30]){

    for(int j=0;j<30;j++){

    str[j]=0;

    }

    }

    void Scanner(){

    sym=fgetc(in);

    if (isspace(sym)){

    while(1){

    if(isspace(sym)){

    sym=fgetc(in);

    }

    else break;

    }

    }

    if(isdigit(sym)){

    while(1){

    if (isdigit(sym)){

    strToken[i]=sym;

    i++;

    sym=fgetc(in);

    }

    else{

    printf("%s",strToken);

    i=0;

    Retract(strToken);

    fseek(in,-2,1);

    sym=fgetc(in);

    break;

    }

    }

    }

    else{

    if(sym=='+'){

    printf("+");

    }

    else if(sym=='-'){

    printf("-");

    }

    else if(sym=='*'){

    printf("*");

    }

    else if(sym=='/'){

    printf("/");

    }

    else if(sym=='^'){

    printf("^");

    }

    else if(sym=='('){

    printf("(");

    }

    else if(sym==')'){

    printf(")");

    }

    }

    }

    void F(){

    if(isdigit(sym)){

    Scanner();

    }

    else if (sym=='('){

    Scanner();

    E();

    if(sym==')'){

    Scanner();

    }

    else error();

    }

    else terror();

    }

    void T1(){

    if(sym=='*'||sym=='/'||sym=='^'){

    Scanner();

    F();

    T1();

    }

    }

    void T(){

    F();

    T1();

    }

    void E1(){

    if (sym=='+'||sym=='-'){

    Scanner();

    T();

    E1();

    }

    }

    void E(){

    T();

    E1();

    }

    void error(){

    printf("\nThis is a wrong phrase!\n");

    exit(0);

    }

    void terror(

    更多相关内容
  • 中国矿业大学编译原理实践课程,C语言编译器之递归下降语法分析器
  • 递归下降语法分析器

    2019-05-08 16:22:34
    c语言编写的递归下降语法分析器的算法,测试成功可以直接跑代码
  • 用C#实现了一个可视化的语法分析器。在textBox1中输入语句,单击START按钮,开始语法分析,在textBox2中输出语法分析过程和语法分析结果。
  • 递归下降语法分析器的实现递归下降语法分析器的实现递归下降语法分析器的实现递归下降语法分析器的实现递归下降语法分析器的实现
  • 编译原理作业,递归下降语法分析器。根据课堂讲授的形式化算法,编制程序实现递归下降分析器,能对常见的语句进行分析。
  • 用java语言编写的递归下降语法分析器用java语言编写的递归下降语法分析器用java语言编写的递归下降语法分析器
  • 语法分析递归下降分析法代码+实验报告
  • 设计递归下降翻译,完成语法分析和中间代码翻译。 输入:一个完整的源程序 输出:与输入对应的一个语法树、四元式序列 2、资源 课设报告word 课设源码 3、开发环境 编程语言:C++ IDE:VS 2019
  • 递归下降语法分析的前提是保证LL(1)文法 递归下降的思路就是暴力dfs。对每个程序直接不管三七二十一搜进去,只要能搜到就继续搜。搜不到就return搜其他的。 先看文法: ① : lexp->atom|list ② :atom->...

    实验目的:
    针对给定的上下文无关文法,编制一个递归下降分析程序。

    分析:

    • 递归下降语法分析的前提是保证LL(1)文法

    递归下降的思路就是暴力dfs。对每个程序直接不管三七二十一搜进去,只要能搜到就继续搜。搜不到就return搜其他的。

    先看文法:

    : lexp->atom|list
    ②	:atom->number|identifier
    ③	:list->(lexp-seq)
    ④	:lexp-seq->lexp-seq lexp|lexp
    
    

    很明显左递归,先消除一下

    : lexp->atom|list
    ②	:atom->number|identifier
    ③	:list->(lexp-seq)
    ④	:lexp-seq->lexp lexp-seq’
    ⑤	: lexp-seq’->lexp lexp-seq’|ε
    
    

    然后直接对input字符流开始递归调用。

    #include<stdio.h>
    #include<cstdlib>
    #include<string.h>
    #define maxn 1000
    using namespace std;
    int idx=0;
    char str[maxn];
    int lexp();
    void atom();
    void list();
    void lexp_sep();
    void lexp_sep_();
    int lexp(){
    	if( (str[idx]>='0'&&str[idx]<='9')||(str[idx]>='a'&&str[idx]<='z') ){
    		printf("lexp->atom\n");
    		atom();
    		return 1;
    	}
    	else if(str[idx]=='('){
    		printf("lexp->list\n");
    		list();
    		return 1;
    	}
    	else return 0;
    }
    void atom(){
    	if(str[idx]>='0'&&str[idx]<='9'){
    		printf("atom->number\n");
    		idx++;
    	}
    	else if(str[idx]>='a'&&str[idx]<='z'){
    		printf("atom->identifier\n");
    		idx++;
    	}
    }
    void list(){
    	if(str[idx]!='('){
    		printf("list()error!\n");
    		exit(-1);
    	}
    	printf("list->(lexp_seq)\n");
    	idx++;
    	lexp_sep();
    	if(str[idx]!=')'){
    		printf("list()error!\n");
    		exit(-1);
    	}
    	idx++;
    }
    void lexp_sep(){
    	printf("lexp_sep->lexp lexp_seq'\n");
    	lexp();
    	lexp_sep_();
    }
    void lexp_sep_(){
    	if(lexp()==1){
    		lexp_sep_();
    	}
    	else return;	
    }
    int main(int argc,char* argv[]){
    	scanf("%s",str);
    	int len=strlen(str);
    	str[len++]='$';str[len]='\0';
    	lexp();	
    	if(str[idx]=='$') printf("accept!\n");
    	else printf("wrong answer!\n");
    	return 0;
    }
    
    

    测试数据:

    (a(b(2))c)
    

    输出结果:

    lexp->list
    list->(lexp_seq)
    lexp_sep->lexp lexp_seq'
    lexp->atom
    atom->identifier
    lexp->list
    list->(lexp_seq)
    lexp_sep->lexp lexp_seq'
    lexp->atom
    atom->identifier
    lexp->list
    list->(lexp_seq)
    lexp_sep->lexp lexp_seq'
    lexp->atom
    atom->number
    lexp->atom
    atom->identifier
    accept!
    
    

    可以看到匹配是能成功的,但是对于想要我们输出该语法树就存在问题了。

    经过思考发现,直接递归下降分析是无法完成语法树的构建输出的,虽然能匹配正确结果。
    原因在于其需要判定递归有效才会输出,因此在决定是否进入的时候不能保证输出此次进去还是不进去。单纯一次递归有效可以用栈判定,但是多次就不行了。
    因此需要构建first集合和follow集合来构建预测分析表。

    当然cyc给每个token额外加了括号来直接dfs搜保证了正确的输出。在这里膜一下

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    #include<iostream>
    #include<stack>
    #include<algorithm>
    #include<string>
    using namespace std;
    stack<string>input;
    stack<string>st;
    bool number(const string& s){
      for(int i=0;i<(int)s.size();i++){
          if(!(s[i]>='0'&&s[i]<='9')) return false;
      }
      return true;
    }
    bool identifier(const string& s){
      for(int i=0;i<(int)s.size();i++){
          if(!(s[i]>='a'&&s[i]<='z')) return false;
      }
      return true;
    }
    int main(){
        input.push("$");
        string s;cin>>s;
        for(int i=(int)s.size()-1;i>=0;i--){
           string tmp;tmp+=s[i];
           input.push(tmp);
        }
        st.push("$");
        st.push("lexp");
        while(st.size()>1){
           string now=st.top();st.pop();
           string cnt=input.top();
           if(now=="lexp"){
             if(cnt=="("){
               cout<<"lexp  -> list"<<endl;
               st.push("list");
             } 
             else if(number(cnt)){
                cout<<"lexp -> atom"<<endl;
                st.push("atom");
             }
             else if(identifier(cnt)){
                cout<<"lexp -> atom"<<endl; 
                st.push("atom");
             }
             else{
                cout<<"lexp()->next error!"<<endl;
                exit(-1);
             }
           }
           else if(now=="atom"){
             if(number(cnt)){
                cout<<"atom -> number"<<endl;
                input.pop();  
             }
             else if(identifier(cnt)){
                cout<<"atom -> identifier"<<endl;
                input.pop();
             }
             else{
                cout<<"atom()->next error!"<<endl;
                exit(-1);
             }
           }
           else if(now=="list"){
             if(cnt=="("){
                cout<<"list -> ( lexp-seq )"<<endl;
                input.pop(); 
                st.push(")");
                st.push("lexp-seq");
             }
             else{
               cout<<"list()-> next errpr!"<<endl;
               exit(-1);
             }
           }
           else if(now=="lexp-seq"){
             if(cnt=="("||number(cnt)||identifier(cnt)){
                cout<<"lexp-seq -> lexp lexp-seq'"<<endl;
                st.push("lexp-seq'");
                st.push("lexp");
             } 
             else{
               cout<<"lexp-seq()->next error!"<<endl;
               exit(-1);
             }
           }
           else if(now=="lexp-seq'"){
             if(cnt=="("||number(cnt)||identifier(cnt)){
                cout<<"lexp-seq'  -> lexp lexp-seq'"<<endl; 
                st.push("lexp-seq'");
                st.push("lexp");
             }
             else{
                cout<<"lexp-seq'  -> NULL"<<endl; 
             }
           }
           else if(now==")"&&cnt==")"){
              input.pop(); 
           }
           else{
              cout<<"Wrong answer"<<endl;
              exit(-1);
           }
        }
        cout<<"Accept!"<<endl;
    }
    
    

    输入:

    (a(b(2))c)
    

    python生成图片:
    在这里插入图片描述

    展开全文
  • 一个关于递归下降语法分析器设计的文档
  • 主要介绍了Python如何实现一个简单的递归下降分析器,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
  • 1、构造LL(1),通过设计、编制、调试递归下降语法分析程序,对输入的符号串进行分析匹配,观察输入符号串是否为给定文法的句子。 2、根据LL(1)写函数和程序 三、预估问题 应确保LL(1)构造成功,不然程序会出错...

    一、实验要求

    运用递归下降法,针对给定的上下文无关文法,给出实验方案。预估实验中可能出现的问题。

     

    二、实验方案

    1、构造LL(1),通过设计、编制、调试递归下降语法分析程序,对输入的符号串进行分析匹配,观察输入符号串是否为给定文法的句子。

    2、根据LL(1)写函数和程序

     

    三、预估问题

    应确保LL(1)构造成功,不然程序会出错

    理论基础

    递归下降分析程序实现思想简单易懂。程序结构和语法产生式有直接的对应关系。因为每个过程表示一个非终结符号的处理,添加语义加工工作比较方便。

    递归下降分析程序的实现思想是:识别程序由一组子程序组成。每个子程序对应于一个非终结符号。

    每一个子程序的功能是:选择正确的右部,扫描完相应的字。在右部中有非终结符号时,调用该非终结符号对应的子程序来完成。

    自上向下分析过程中,如果带回溯,则分析过程是穷举所有可能的推导,看是否能推导出待检查的符号串。分析速度慢。而无回溯的自上向下分析技术,当选择某非终结符的产生时,可根据输入串的当前符号以及各产生式右部首符号而进行,效率高,且不易出错。

    无回溯的自上向下分析技术可用的先决条件是:无左递归和无回溯。

    无左递归:既没有直接左递归,也没有间接左递归。

    无回溯:对于任一非终结符号U的产生式右部x1|x2|…|xn,其对应的字的首终结符号两两不相交。

    如果一个文法不含回路(形如P⇒+ P的推导),也不含以ε为右部的产生式,那么可以通过执行消除文法左递归的算法消除文法的一切左递归(改写后的文法可能含有以ε为右部的产生式)。

     

    四、内容和步骤

    1、针对4.8习题输入和输出的设计及代码

     

    2、针对现场给定语法的设计和处理

    【考虑简单算术表达式文法G:

    E→E + T | T

    T→T * F | F

    F→(E) | id

    试设计递归下降分析程序,以对任意输入的符号串进行语法分析。】

     

    3、实验具体步骤

    (1)输入字符串,后并加上$符号

    (2)匹配字符,若成功,输出并换行,若遇到非终结符,输出空格,若遇到错误,输出字符和位置。

     

    针对给定语法进行设计:

    E->E+T|T
    T->TF|F
    F->(E)|id
    E->TE’
    E’->+TE’|ε
    T->FT’
    T’->FT’|ε
    F->(E)|id
    First(E)={(,id}
    First(E’)={+, ε}
    First(T)={(,id}
    First(T’)={, ε}
    First(F)={(,id}
    Follow(E)={KaTeX parse error: Expected 'EOF', got '}' at position 3: ,)}̲ Follow(E’)={,)}
    Follow(T)={+,KaTeX parse error: Expected 'EOF', got '}' at position 3: ,)}̲ Follow(T’)={+,,)}
    Follow(F)={*,+,$,)}

    五、实验结果

    代码

    #include<iostream> 
    #include<string>
    #include<math.h>
    using namespace std;
    string str;
    int pos;
    bool flag;
    void lexp_seq();
    void lexp_seq1();
    char judge(char ch)
    {
    	if(ch >= '0' && ch <= '9') return 'n';
    	else if((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) return 'a';
    	else return ch;
    }
    void error(char ch)
    {
    	if (flag) return;
    	else flag = false;
    	cout<<endl<<"error:"<<ch<<",position:"<<pos;
    }
    
    void match(char kind, char ch)
    {
    	cout<<kind<<": "<<ch<<endl;
    	pos++;
    }
    
    void atom()
    {
    	if(!flag) return;
    	char ch= judge(str[pos]);
    	if(ch=='n') match('n', str[pos]);
    	else if(ch=='a') match('a', str[pos]);
    	else if(ch=='$') cout<<"accept"<<endl;
    	else error(ch);
    }
    void list()
    {
    	if(!flag) return;
    	match('l', '(');
    	cout<<" ";
    	lexp_seq1();
    	if(str[pos] == ')') match('r',')');
    	else error(str[pos]);
    }
    
    void lexp()
    {
    	if(!flag) return;
    	char ch= judge(str[pos]);
    	if(ch == 'n' || ch == 'a'){cout<<" ";atom();}
    	else if(ch == '('){cout<<" ";list();}
    	else if(ch == '$' ) cout<<"accept"<<endl;
    	else error(ch);
    }
    
    void lexp_seq1()
    {
    	if(!flag) return;
    	char ch= judge(str[pos]);
    	if(ch == 'n' || ch == 'a' || ch == '(') {
    		cout<<" ";
    		lexp();
    		cout<<" ";
    		lexp_seq1();
    	}
    	else if(ch == ')') match('r', ')');
    	else if(ch == '$') cout<<"accept"<<endl;
    	else error(ch);
    }
    
    int main()
    {
    	pos = 0;
    	flag = true;
    	cin>>str;
    	str +='$';
    	lexp_seq1();
    	return 0;
    }
    

    截图

     

    六、实验结论

    1 、实验结论

    通过设计、编制、调试递归下降语法分析程序,对输入的符号串进行分析匹配,观察输入符号串是否为给定文法的句子,输出其语法树。

    2、分析和总结

    1)对输入设计的结论

    按照4.8的输入

    2)对输出设计的结论

    输出一个语法树,不受界面尺寸限制

    3)对递归下降法的算法的结论

    递归下降分析法是一种自顶向下的分析方法,文法的每个非终结符对应一个递归过程(函数)。分析过程就是从文法开始符出发执行一组递归过程(函数),

    这样向下推导直到推出句子;或者说从根节点出发,自顶向下为输入串寻找一个最左匹配序列,建立一棵语法树。

     

    3、对预估问题的结论

    预估问题未发生

    资源下载

    第四次上机作业 语法分析2

    参考文章

    《编译原理》实验预习报告——递归下降语法分析器的构建

    编译原理 实验4《递归下降分析法设计与实现》

    编译原理实验二 递归下降语法分析器的构建

    编译原理与实践第四章答案

    展开全文
  • 对于以下代码给出其递归下降语法分析过程: { i=2; while(i<=100) { sum=sum+i; i=i+2; } } 具体实现: 首先对上下文无关文法进行检查,消除左递归和左公共因子,从逻辑上检测避免死循环和低效率处理...

    内容:

    实现以下语法的递归下降分析:
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述

    示例:

    对于以下代码给出其递归下降语法分析过程:

    {
    	i=2;
    	while(i<=100)
    	{
    		sum=sum+i;
    		i=i+2;
    	}
    }
    

    在这里插入图片描述

    具体实现:

    • 首先对上下文无关文法进行检查,消除左递归和左公共因子,从逻辑上检测避免死循环和低效率处理。
    • 采用每个产生式的左边的文法符号对应一个函数或过程的形式,编写程序实现一个递归下降分析器。
    • 语法分析是在词法分析的基础上进行的(关于词法分析的实现,具体参见我的上篇博客->【编译原理与技术】词法分析器(C++实现))。

    C++代码:

    #include<cstdio>
    #include<cstring>
    #include<ctype.h>
    #include<iostream>
    using namespace std;
    char prog[1000],ch,ch1,token[1000],filename[30];
    int p=0,sym=0,n,line=1;
    FILE *fpin;
    const char *keyword[22]={"if","else","while","do","main","int","float","for"
     						"double","return","const","void","continue","break","char",
    						 "signed","enum","long","switch","case","auto","unsigned"};
    char keywordtable[20][20];                 //存放保留字
    char digittable[20][20];                   //存放数字
    char otherchartable[20][20];           		//存放其他字符
    char idtable[20][20];                        //存放标识符
    char notetable[20][20];                      //存放注释
    char finaltable[100][20];              		//存放终结符
    int finaltableint[100];
    char word[20];
    void initialize();
    void alpha();
    void digit();
    void error();
    void otherchar();
    void note();
    void program();
    void block();
    void stmts();
    void stmt();
    void Bool();
    void expr();
    void expr1();
    void term();
    void term1();
    void factor();
    void YufaBegin();
    void CifaBegin();
    void GetToken();
    void match(string str);
    int digit_num=0,keyword_num=0,otherchar_num=0,id_num=0,note_num=0;
    int final_num=0,finalnum=0;
    int flag_error=0;                                  //0表示没有错误,1表示有错误 
    int flagerror=0;
    
    int main()
    {
        cout<<"请输入源文件名:";
     	while(1)
     	{
     		cin>>filename;
     		if((fpin=fopen(filename,"r"))!=NULL)//只读	
     		{ 	
    			break;
    		}		
    		else
    			cout<<"文件输入错误!请输入源文件名:";	
    	}
    	//将文件内容存储到prog中 
    	do
    	{
    		ch=fgetc(fpin);
    	 	prog[p++]=ch;
    	}while(ch!=EOF);
    	//调用词法分析部分 
    	printf("-----------------\n");
    	printf("词法分析结果如下:\n");
    	rewind(fpin);
    	ch=fgetc(fpin);
    	CifaBegin();
        //调用语法分析部分
    	rewind(fpin); 
        ch=fgetc(fpin);		
    	initialize();
        YufaBegin();
    	return 0;
    }  
    void YufaBegin(){
    	p=0;
    	while(1)
        {	
        	ch=prog[p++];  
    		if(ch==EOF) break;            
        	if(isalpha(ch)||ch=='_')                    
    		                                          //a-z或A-Z时返回非零值(不一定是1),否则返回零 
        	{
        		alpha();
        		initialize();
    		}
    		else if(isdigit(ch))               //用来判断字符lookahead是否为数字 
    		{
    			digit();
    			initialize();
    		}
    		else if(ch=='\t'||ch==' '||ch=='\n')
    		{
    			continue;
    		}
    		else if(ch=='/')
    		{
    			ch=prog[p++];
    			if(ch=='*'||ch=='/')
    			{
    				note();
    				initialize();
    			}
    			else
    			{
    				p--;                          					//把一个字符退回到输入流中
    				                                                  //lookahead是写入的字符,stdin是文件流指针 
    				strcpy(finaltable[final_num],"/");                //将"/"放到终结符号表中 
    				strcpy(otherchartable[otherchar_num++],"/");      //将"/"放到其他符号表中 
    				finaltableint[final_num++]=2;                     //"/"的序号是2 
    				initialize();
    			}
    		}
    		/*else if(ch=='#'){
    			break;
    		}*/
    		else
    		{
    			otherchar();
    			initialize();
    		}
    	}
    	if(flag_error==0)
    	{
    		finaltableint[final_num]='\0';
    		printf("--------------------");
    		printf("\n语法分析过程如下:\n");
    		program();
    		if(finalnum==final_num)
                printf("语法分析完成!");		
    	}
    }  
    void alpha()
    {
        int i=0,flag;
    	word[i++]=ch;
    	ch=prog[p++];
    	while(isalpha(ch)||isdigit(ch))                                //将标识符放到word数组中 
    	{
    		word[i++]=ch;
    		ch=prog[p++];
    	}	
    	p--;
    	flag=0;
    	for(i=0;i<21;i++)
    	{
    		if(strcmp(word,keyword[i])==0){
    			flag=1;
    			break;
    		}
    		
    	}
    	//在这里我只实现了部分保留字,大家可根据要求自行增删
    	if(flag==1)
    	{
    		strcpy(keywordtable[keyword_num++],word);
    		strcpy(finaltable[final_num],word);
    		if(strcmp(word,"if")==0)
    		    finaltableint[final_num++]=100;
    		if(strcmp(word,"for")==0)
    		    finaltableint[final_num++]=200;
    		if(strcmp(word,"else")==0)
    		    finaltableint[final_num++]=300;
    		if(strcmp(word,"while")==0)
    		    finaltableint[final_num++]=400;
    		if(strcmp(word,"do")==0)
    		    finaltableint[final_num++]=500;
    		if(strcmp(word,"float")==0)
    		    finaltableint[final_num++]=600;
    		if(strcmp(word,"int")==0)
    		    finaltableint[final_num++]=700;
    		if(strcmp(word,"break")==0)
    		    finaltableint[final_num++]=800;
    	}
    	else
    	{
    		strcpy(idtable[id_num++],word);
    		strcpy(finaltable[final_num],"id");
    		finaltableint[final_num++]=1;
    	}
    }
    void initialize()
    {
    	for(int i=0;i<20;i++)
    	{
    		word[i]='\0';
    	}
    }
    void digit()
    {
     	int i=0,flag;
     	word[i++]=ch;
     	ch=prog[p++];
     	while(isdigit(ch))
    	{
    		word[i++]=ch;
    		ch=prog[p++];
    	}	
    	p--;
    	strcpy(digittable[digit_num++],word);
    	strcpy(finaltable[final_num],"num");//数字数组,序号为99 
    	finaltableint[final_num++]=99;
    	
    }	
    void note()
    {
    	int i=0;
    	while(1)
    	{
    		if(ch=='*')
    		{
    			ch=prog[p++];
    			if(ch=='/')
    			   break;
    			else
    			{
    			   p--;
    			   word[i++]=ch;	
    			}  
    		}
    		else if(ch=='\n'){
    			break;
    		}
    		else
    		{
    			word[i++]=ch;
    		}
    		ch=prog[p++];
    	}
    	strcpy(notetable[note_num++],word);//将注释的内容放入注释表 
    }
    void otherchar()
    {
    	switch(ch){
    	case '!':
    		{
    			ch=prog[p++];
    			if(ch=='=')
    			{
    				strcpy(otherchartable[otherchar_num++],"!=");
    				strcpy(finaltable[final_num],"!=");
    				finaltableint[final_num++]=3;
    			}
    			else
    			{
    				p--;
    				error();
    			}
    		}
    		break;
    	case '=':
    	    {
    		    ch=prog[p++];
    		    if(ch=='=')
    	    	{
    			    strcpy(otherchartable[otherchar_num++],"==");
    				strcpy(finaltable[final_num],"==");
    				finaltableint[final_num++]=4;
    		    }
    		    else
    		    {
    		    	strcpy(otherchartable[otherchar_num++],"=");
    				strcpy(finaltable[final_num],"=");
    				finaltableint[final_num++]=5;
    				p--;
    			}
    		}
    		break;
    	case '(':
    		strcpy(otherchartable[otherchar_num++],"(");
    		strcpy(finaltable[final_num],"(");
    		finaltableint[final_num++]=6;
    		break;
    	case ')':
    		strcpy(otherchartable[otherchar_num++],")");
    		strcpy(finaltable[final_num],")");
    		finaltableint[final_num++]=7;
    		break;
    	case ';':
    		strcpy(otherchartable[otherchar_num++],";");
    		strcpy(finaltable[final_num],";");
    		finaltableint[final_num++]=8;
    		break;
    	case '{':
    		strcpy(otherchartable[otherchar_num++],"{");
    		strcpy(finaltable[final_num],"{");
    		finaltableint[final_num++]=9;
    		break;
    	case '}':
    		strcpy(otherchartable[otherchar_num++],"}");
    		strcpy(finaltable[final_num],"}");
    		finaltableint[final_num++]=10;
    		break;
    	case '|':
    		{
    			ch=prog[p++];
    			if(ch=='|')
    			{
    				strcpy(otherchartable[otherchar_num++],"||");
    				strcpy(finaltable[final_num],"||");
    				finaltableint[final_num++]=11;
    			}
    			else
    			{
    				p--;
    				error();
    			}
    		
    		} 
    		break;
    	case '&':
    		{
    			ch=prog[p++];
    			if(ch=='&')
    			{
    				strcpy(otherchartable[otherchar_num++],"&&");
    				strcpy(finaltable[final_num],"&&");
    				finaltableint[final_num++]=12;
    			}
    			else
    			{
    				p--;
    				error();
    			}
    		} 
    		break;
    	case '+':
    		strcpy(otherchartable[otherchar_num++],"+");
    		strcpy(finaltable[final_num],"+");
    		finaltableint[final_num++]=13;
    		break;
    	case '-':
    		strcpy(otherchartable[otherchar_num++],"-");
    		strcpy(finaltable[final_num],"-");
    		finaltableint[final_num++]=19;
    		break;
    	case '>':
    		{
    			ch=prog[p++];
    			if(ch=='=')
    			{
    				strcpy(otherchartable[otherchar_num++],">=");
    		        strcpy(finaltable[final_num],">=");
    				finaltableint[final_num++]=14;
    			}
    			else
    			{
    				strcpy(otherchartable[otherchar_num++],">");
    				strcpy(finaltable[final_num],">");
    				finaltableint[final_num++]=15;
    				p--;
    			}
    		}
    		break;
    	case '<':
    		{
    			ch=prog[p++];
    			if(ch=='=')
    			{
    				strcpy(otherchartable[otherchar_num++],"<=");
    		        strcpy(finaltable[final_num],"<=");
    				finaltableint[final_num++]=16;
    			}
    			else
    			{
    				strcpy(otherchartable[otherchar_num++],"<");
    				strcpy(finaltable[final_num],"<");
    				finaltableint[final_num++]=17;
    				p--;
    			}
    		}
    		break;
    	case '*':
    		strcpy(otherchartable[otherchar_num++],"*");
    		strcpy(finaltable[final_num],"*");
    		finaltableint[final_num++]=18;
    		break;
    	default:
    		error();
    		break;
    	}
    }
    void error()
    {
    	flag_error=1;
    	printf("出现错误,停止分析!\n");
    }
    void program()
    {
    	printf("program-->block\n");
    	block();
    	if(flagerror==1)
    	{
    		error();
    		return;
    	}
    }
    void block()
    {
    	if(flagerror==1)
    	{
    		return;
    	}
    	printf("block-->{stmts}\n");
    	match("{");
    	stmts();
    	match("}"); 
    }
    void stmts()
    {
    	if(flagerror==1)
    	{
    		return;
    	}
    	//cout<<"stmts():"<<finaltableint[finalnum]<<endl;
    	if(finaltableint[finalnum]==10)
    	{
    		printf("stmts-->null\n");
    		return;
    	}
    	printf("stmts-->stmt stmts\n");
    	stmt();
    	stmts();
    }
    void stmt()
    {
    	if(flagerror==1)
    	{
    		return;
    	}
    	//cout<<"stmt():"<<finaltableint[finalnum]<<endl;
    	switch(finaltableint[finalnum])
    	{
    	case 1:
    		printf("stmt-->id=expr;\n");
    		match("id");
    		match("=");
    		expr();
    		match(";");
    		break;
    	case 100:
    		match("if");
    		match("(");
    		Bool();
    		match(")");
    		stmt();
    		if(strcmp(finaltable[finalnum],"else")==0)
    		{
    			printf("stmt-->if(bool) stmt else stmt\n");
    			match("else");
    			stmt();
    			break;
    		}
    		else
    		{
    		    printf("stmt-->if(bool) stmt\n");
    			break;	
    		}
    	case 400:
    		printf("stmt-->while(bool) stmt\n");
    		match("while");
    		match("(");
    		Bool();
    		match(")");
    		stmt();
    		break;
    	case 500:
    		printf("stmt-->do stmt while(bool)\n");
    		match("do");
    		stmt();
    		match("while");
    		match("(");
    		Bool();
    		match(")");
    		break;
    	case 800:
    		printf("stmt-->break\n");
    		match("break");
    		break;
    	default:
    		printf("stmt-->block\n");
    		block();
    		break;
    	}
    }
    void Bool()
    {
    	if(flagerror==1)
    	{
    		return;
    	}
    	expr();
    	switch(finaltableint[finalnum])
    	{
    	case 17:
    		printf("bool-->expr < expr\n");
    		match("<");
    		expr();
    		break;
    	case 16:
    		printf("bool-->expr <= expr\n");
    		match("<=");
    		expr();
    		break;
    	case 15:
    		printf("bool-->expr > expr\n");
    		match(">");
    		expr();
    		break;
    	case 14:
    		printf("bool-->expr >= expr\n");
    		match(">=");
    		expr();
    		break;
    	default:
    		printf("bool-->expr\n");
    		expr();
    		break;
    	}
    }
    void expr()
    {
    	if(flagerror==1)
    	{
    		return;
    	}
    	printf("expr-->term expr1\n");
    	term();
    	expr1();
    }
    void expr1()
    {
    	if(flagerror==1)
    	{
    		return;
    	}
    	//cout<<"expr1():"<<finaltableint[finalnum]<<endl;
    	switch(finaltableint[finalnum])
    	{
    	case 13:
    		printf("expr1-->+term expr1\n");
    		match("+");
    		term();
    		expr1();
    		break;
    	case 19:
    		printf("expr1-->-term expr1\n");
    		match("-");
    		term();
    		expr1();
    		break;
    	default:
    		printf("expr1-->null\n");
    		return;
    	}
    }
    void term()
    {
    	if(flagerror==1)
    	{
    		return;
    	}
    	printf("term-->factor term1\n");
    	factor();
    	term1();
    } 
    void term1()
    {
    	if(flagerror==1)
    	{
    		return;
    	}
    	//cout<<"term1():"<<finaltableint[finalnum]<<endl;
    	switch(finaltableint[finalnum])
    	{
    	case 18:
    		printf("term1-->*factor term1\n");
    		match("*");
    		factor();
    		term1();
    		break;
    	case 2:
    		printf("term1-->/factor term1\n");
    		match("/");
    		factor();
    		term1();
    		break;
    	default:
    		printf("term1-->null\n");
    		return;
    	}
    }
    void factor()
    {
    	if(flagerror==1)
    	{
    		return;
    	}
    	//cout<<"factor():"<<finaltableint[finalnum]<<endl;
    	switch(finaltableint[finalnum])
    	{
    	case 6:
    		printf("factor-->(expr)\n");
    		match("(");
    		expr();
    		match(")");
    		break;
    	case 1:
    		printf("factor-->id\n");
    		match("id");
    		break;
    	case 99:
    		printf("factor-->num\n");
    		match("num");
    		break;
    	default:
    		flagerror=1;
    		break;
    	}
    }
    void match(string str)
    {
    	char cha[20];
    	for(int i=0;i<20;i++){
    		cha[i]='\0';
    	}
    	for(int k=0;k<str.length();k++){
    		cha[k]=str[k];
    	}
    	//cout<<finaltable[finalnum]<<endl;
    	//cout<<cha<<endl;
    	if(strcmp(finaltable[finalnum],cha)==0){
    		//cout<<"1"<<endl;
    	}
    	else
    	{
    		flagerror=1;
    		return;
    	}
    	finalnum++;
    }
    
    
    //--------------
    //词法分析器部分 
    void CifaBegin()
    {
    	p=0;
    	do 
    	{
    		GetToken();//启动字符识别函数 
    		//if(ch==EOF) break; 
    		switch(sym)//打印字符状态 
    		{
    			case 1:cout<<"("<<line<<" "<<token<<" "<<"标识符"<<")"<<endl;break;
    			case 2:cout<<"("<<line<<" "<<token<<" "<<"保留字"<<")"<<endl;break;
    			case 3:cout<<"("<<line<<" "<<token<<" "<<"整型"<<")"<<endl;break;
    			case 31:cout<<"("<<line<<" "<<token<<" "<<"浮点型"<<")"<<endl;break;
    			case 32:cout<<"("<<line<<" "<<token<<"S"<<" "<<"短类型"<<")"<<endl;break;
    			case 33:cout<<"("<<line<<" "<<token<<"L"<<" "<<"长类型"<<")"<<endl;break;
    			case 34:cout<<"("<<line<<" "<<token<<"O"<<" "<<"八进制数"<<")"<<endl;break;
    			case 35:cout<<"("<<line<<" "<<token<<"H"<<" "<<"十六进制数"<<")"<<endl;break;
    			case 4:cout<<"("<<line<<" "<<token<<" "<<"特殊符号"<<")"<<endl;break;
    			case -1:cout<<"("<<line<<" "<<"错误!"<<")"<<endl;break;
    			default:break;
    		}
    	}while(ch!=EOF);
    	p=0;
    }
    void GetToken() 
    {
     	sym=0;
    	 //先把token[]数组清空 
     	for (n=0;n<1000;n++)
     	{
     		token[n]='\0';
    	}
    	n=0;
    	ch=prog[p++];
    	ch1=prog[p];
    	//跳过空格,回车,tab的识别 
    	while(ch==' '||ch=='\t')
    	{
    		ch=prog[p++];
    	}
    	if(ch=='\n'){
    		line++;
    		return;
    	}
    	if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch=='_')) 
    	{
    		//标识符 状态1
    		sym=1;
    		do{
    			token[n++]=ch;
    			ch=prog[p++];
    		}while ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'));
    		//比较标识符与keyword的关键字是否相同,若相同转为状态2
    		for(n=0;n<2;n++)
    		{
    			if(strcmp(token,keyword[n])==0){
    				sym=2;
    				break;	
    			}
    		}
    		p--;
    		return;
    	}
    	
    	else if (ch>='0'&&ch<='9') 
    	{	
    		//识别到数字,置状态为3
    		sym=3;
    		do
    		{	
    			token[n++]=ch;
    			ch=prog[p++];
    			if(ch=='.'){
    				sym=31;
    				token[n++]=ch;
    				ch=prog[p++];
    			}
    			if(ch=='S'){
    				sym=32;
    				ch=prog[p++];
    			} 
    			if(ch=='L'){
    				sym=33;
    				ch=prog[p++];
    			}
    			if(ch=='O'){
    				sym=34;
    				ch=prog[p++];
    			}	
    			if(ch=='H'){
    				sym=35;
    				ch=prog[p++];
    			}		
    		}while(ch>='0'&&ch<='9'); 
    		p--;
    		return;
    	}
    	//跳过注释的内容 
    	else if(ch=='/' && ch1=='*')
    	{	
    		p++;
    		do{
    			ch=prog[p++];
    			ch1=prog[p++];
    			if(ch=='\n'){
    				line++;
    			}
    		}while(ch!='*'||ch1!='/');
    		return;
    	}
    	else if(ch=='/'&& ch1=='/')
    	{
    		p++;
    		do{
    			ch=prog[p++];
    		}while(ch!='\n');
    		line++;
    		return;
    	}
    	else if(ch=='='&& ch1=='='){
    		p++;
    		sym=4;
    		token[0]='=';
    		token[1]='=';
    		return;
    	}
    	else if(ch=='<'&& ch1=='='){
    		p++;
    		sym=4;
    		token[0]='<';
    		token[1]='=';
    		return;
    	}
    	else if(ch=='>'&& ch1=='='){
    		p++;
    		sym=4;
    		token[0]='>';
    		token[1]='=';
    		return;
    	}
    	else if(ch=='!'&& ch1=='='){
    		p++;
    		sym=4;
    		token[0]='!';
    		token[1]='=';
    		return;
    	}		
    	else if(ch=='&'&& ch1=='&'){
    		p++;
    		sym=4;
    		token[0]='&';
    		token[1]='&';
    		return;
    	}	
    	else if(ch=='|'&& ch1=='|'){
    		p++;
    		sym=4;
    		token[0]='|';
    		token[1]='|';
    		return;
    	}
    	else 
    	{
    		switch(ch)//识别关键符号 
    		{	
    			case '=':
    			case '<':
    			case '>':
    			case '/':
    			case '+':
    			case '-':
    			case '*':
    			case '{':
    			case '}':
    			case ';':
    			case '(':
    			case ')':
    			case ',':
    			case '\'':
    			case '\"':sym=4;token[0]=ch;break;
    			default:sym=-1;break;
    		}
    	}
    	return;
     }
    
    
    
    

    运行结果:

    在这里插入图片描述

    展开全文
  • 递归下降语法分析器C++实现

    热门讨论 2009-05-24 01:32:00
    一个简单的递归下降语法分析器,C++实现,主要是理解编译原理
  • 编译实验——递归下降语法分析器 实验内容: 根据课堂讲授的形式化算法,编制程序实现递归下降分析器,能对常见的语句进行分析。 要求实现以下语法的递归下降分析: 算法分析: 1. 算法设计: 递归下降的语法分析...
  • 实现了c语言的算术表达式的语法分析,用的是递归下降分析法。程序简单易懂
  • 递归下降语法分析程序的范例代码...实验内容及操作示范详见实验指导书...
  • 《编译原理》实验二-递归下降语法分析器的构建-实验报告一、实验要求二、实验方案三、预估问题1、预估问题2、理论基础四、内容和步骤1、针对4.8习题输入和输出的设计及代码2、针对现场给定语法的设计和处理3、实验...
  • a.选择测试代码,begin a:=9;x:=2*3;b:=a+xend#,即词法分析器的输入,所示。 b.统计测试程序包含的单词符号,假定关键字、界符、运算符都是一符一种,设计单词符号对应的种别码,如表1 ...//递归下降语法分析程序 #...
  • 实验二 语法分析—(1)递归下降分析法 程序输入/输出示例: 对下列文法,用递归下降分析法对任意输入的符号串进行分析: (1)E->eBaA (2)A->a|bAcB (3)B->dEd|aC (4)C->e|dC 输出的格式如下: (1)递归...
  • 编译原理-递归下降语法分析器(Java)

    万次阅读 多人点赞 2017-04-25 08:37:01
    递归下降语法分析器:判断语法是否正确。 以简单的加减乘除和括号为例。首先我们先分析它的语法。 括号要有一对出现,不能出现单个括号不能出现连续的算术符号,比如两个加号必须以字符开头和字符结尾 ...
  • BNF 递归下降语法分析器 文法: E->E+T|T T->T*F|F F->(E)|i
  • 上一篇《有错误处理功能的递归下降语法分析器》的继续 相信不少同学们是第二次看见我了 笑 上一篇传送门有错误处理功能的递归下降语法分析器 这次的要求:   同步记号集合,i,list来模拟一个栈的想法与上一篇...
  • 递归下降法实现语法分析器源代码(java语言编写),将src文件导入eclipse工程即可运行处结果。
  • LL(1)递归下降语法分析器 /* E->TQ Q->+TQ|e T->FR R->*FR|e F->a|(E) */ #include<iostream> #include<cstdio> #include<string> #include<vector> #include<cstring...
  • 词法分析器的功能是利用函数之间的递归调用模拟语法树自上而下的构造过程。 2、递归下降分析法的前提 改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL(1)文法, 3、递归下降分析法实验设计思想及算法...
  • 以下描述算术表达式的LL(1)文法的递归下降分析程序构造 G[E]: E→TE′ E′→+TE′|ε T→FT′ T′→*FT′|ε F→(E)|i 说明:终结符号i为用户定义的简单变量,即标识符的定义。 要求具有如下功能: 1)从终端...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 54,403
精华内容 21,761
关键字:

递归下降语法分析器