精华内容
下载资源
问答
  • 语法分析器c语言编写
    千次阅读
    2021-07-08 19:30:31

    一、前言

    词法分析和语法分析是编译原理中必要的部分,是需要花费一定时间去学习理解的,本文简单介绍了使用c语言如何编写c语言的词法分析器。(ps:完整代码的链接在文末)

    二、什么是词法分析器

    定义

    词法分析器的功能输入源程序,按照构词规则分解成一系列单词符号。单词是语言中具有独立意义的最小单位,包括关键字、标识符、运算符、界符和常量等。
    (1) 关键字:是由程序语言定义的具有固定意义的标识符。例如begin,end,if,while都是保留字。这些字通常不用作一般标识符。
    (2) 标识符:用来表示各种名字,如变量名,数组名,过程名等等。
    (3) 常数 :常数的类型一般有整型、实型、布尔型、文字型等。
    (4) 运算符:如+、-、*、/等等。
    (5) 界符 :如逗号、分号、括号、等等。

    输出

    有了对词法分析器的定义,我们编写的词法分析器的输出理所当然应当是如下的形式:
    (单词,单词属性,id(种别码))
    如:(if,关键字,3)
    id通常情况下可以自己定义,例如无符号整数的id可以设为1,只要能区别不同的属性即可。(ps:如果在编写时有对应的种别码表,照着写就完事儿了。)

    种别码表示例
    
    单词符号种别码
    NUM0
    Letter1
    main2

    三、实现过程

    如何实现

    1. 读到空格则略过,读下一个字符;若读到的是字母,就再接着读,直到读到的既不是字母也不是数字也不是下划线,并将读到的写入到token数组
    2. 若读到的是数字,直到读到的不是数字或小数点,将读到的写入到token数组;
    3. 若读到的是<|>|=,则再读入下一位,若为=,则该运算符为<=|>=|==,若为其他字符,则返回<|>|=的种别码;
    4. 若读到的是/,则读下一位,若为*,则说明之后为多行注释,一直读入直到读入*,并判断下一位是否为/,若是则注释结束,不是继续往下一位读入;若读入\n,则行数加一,若读入的字符与以上都不匹配,则报错,并输出出错行数;
    5. 若读到/时,下一位又读到/,即读到的是单行注释,此时判断下一位是否为\n,若是,则注释结束,不是则继续读入下一位。

    部分代码

    --建立分析时的缓冲空间
    
    char ch =' ';	//存放读入当前的输入字符
    int Line_NO;	//纪录行号
    
    --建立关键字表
    
    struct keywords{	//关键字
    	char lexptr[MAXBUF];
    	int token;
    };
    
    struct keywords symtable[MAX];
    char str[MAX][10]={"int","char","float","main","double","case","for","if","auto","else","do","while","void","static","return","break","struct","const","union","switch","typedef","enum"};	//记为3~24
    
    --初始化关键字表
    
    void init(){	//关键字表初始化
    	int j;
    	for(j=0; j<MAX; j++){
    	   strcpy(symtable[j].lexptr,str[j]);
    	   symtable[j].token=j+3;
    	}
    }
    
    --Iskeyword函数分析关键字
    
    int Iskeyword(char * is_res){	//对关键字进行搜索
        int i;
        for(i=0;i<MAX;i++){
        	if((strcmp(symtable[i].lexptr,is_res))==0) 
    	 		break;
       }
    	if(i<MAX)
       		return symtable[i].token;		
    	else
    		return 0;
    }
    
    --IsLetter函数分析字母
    
    int IsLetter(char c){	//判断是否为字母
       	if(((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z')))
       		return 1;
        else
    		return 0;
    }
    
    --IsDigit函数分析数字
    
    int IsDigit(char c){	//判断是否为数字
       	if(c>='0'&&c<='9')
       		return 1;
       	else
    	   	return 0;
    }
    
    --碰到空格、tab跳过
    
    if(ch==' '||ch=='\t'){}
    else if(ch=='\n')
    	Line_NO++;
    
    --忽略大小写
    
    if((ch<='A')&&(ch>='Z'))     
    	ch=ch+32;
    
    --字符的处理,包括注释的去除,非法字符
    
    switch(ch){	//符号
    	case'(' :fprintf(fpout,"%s\t\t%d\t\t分界符\n","(",26);break;
    	case')' :fprintf(fpout,"%s\t\t%d\t\t分界符\n",")",27);break;
    	case'[' :fprintf(fpout,"%s\t\t%d\t\t分界符\n","[",28);break;
    	case']' :fprintf(fpout,"%s\t\t%d\t\t分界符\n","]",29);break;
    	case';' :fprintf(fpout,"%s\t\t%d\t\t分界符\n",";",30);break;
    	case'.' :fprintf(fpout,"%s\t\t%d\t\t分界符\n",".",31);break;
    	case',' :fprintf(fpout,"%s\t\t%d\t\t分界符\n",",",32);break;
    	case':' :fprintf(fpout,"%s\t\t%d\t\t分界符\n",":",33);break;
    	case'{' :fprintf(fpout,"%s\t\t%d\t\t分界符\n","{",34);break;
    	case'}' :fprintf(fpout,"%s\t\t%d\t\t分界符\n","}",35);break;
    	case'"' :fprintf(fpout,"%s\t\t%d\t\t分界符\n","\"",36);break;
    	case'+' :fprintf(fpout,"%s\t\t%d\t\t运算符\n","+",37);break;
    	case'-' :fprintf(fpout,"%s\t\t%d\t\t运算符\n","-",38);break;
    	case'*' :fprintf(fpout,"%s\t\t%d\t\t运算符\n","*",39);break;
    	case'=' :fprintf(fpout,"%s\t\t%d\t\t运算符\n","=",40);break;
    	case'>' :{
    		ch=fgetc(fpin);
    		if(ch=='=') 
    			fprintf(fpout,"%s\t\t%d\t\t运算符\n",">=",41);
    		else{
    			fprintf(fpout,"%s\t\t%d\t\t运算符\n",">",42);
    			fseek(fpin,-1L,SEEK_CUR);
    		}
    	}break;
    	case'<' :{
    		ch=fgetc(fpin);
    		if(ch=='=')
    			fprintf(fpout,"%s\t\t%d\t\t运算符\n","<=",43);
    		else{
    			fprintf(fpout,"%s\t\t%d\t\t运算符\n","<",44);
    			fseek(fpin,-1L,SEEK_CUR);}
    	}break;
    	case'%' :{
    		ch=fgetc(fpin);
    	    if(ch=='d'||ch=='f'||ch=='s'||ch=='x')
    	        fprintf(fpout,"%s\t\t%d\t\t输出格式符\n","\%",45);
    		else
    			fprintf(fpout,"%s\t\t%d\t\t运算符\n","\%",46);
    	}break;
    	case'/' :{
    		ch=fgetc(fpin);//出现在/  /之间的全部作为注释部分处理
    		if(ch=='*'){
    	    	while(ch!='/'&&ch!=EOF)
    				ch=fgetc(fpin);
    	        if(ch==EOF) 
    				fprintf(fpout,"缺少一个'/'");
    		}
    		else if(ch=='/'){
    			while(ch!='\n'&&ch!=EOF)
    				ch=fgetc(fpin);
    		}
    		else{
    			fprintf(fpout,"%s\t\t%d\t\t运算符\n","/",47);
    			fseek(fpin,-1L,SEEK_CUR);
    		}
    	}break;
    	default :fprintf(fpout,"在第%d行无法识别的字符\t%c\n",Line_NO,ch);	//非法字符 
    }
    

    四、测试

    测试用例

    测试文件s.txt

    int main(void)
    {
       int a1,b;
       a1=103;
       b=2;
       if(a1>=b){/*多行
    注释*/
       	a1=a1*b;//单行注释
       }
       printf("%d",a1);
       return 0;
    }
    

    输出结果

    输出文件r.txt

    int		3		关键字
    main	6		关键字
    (		26		分界符
    void	15		关键字
    )		27		分界符
    {		34		分界符
    int		3		关键字
    a1		1		标识符
    ,		32		分界符
    b		1		标识符
    ;		30		分界符
    a1		1		标识符
    =		40		运算符
    103		2		无符号整数
    ;		30		分界符
    b		1		标识符
    =		40		运算符
    2		2		无符号整数
    ;		30		分界符
    if		10		关键字
    (		26		分界符
    a1		1		标识符
    >=		41		运算符
    b		1		标识符
    )		27		分界符
    {		34		分界符
    a1		1		标识符
    =		40		运算符
    a1		1		标识符
    *		39		运算符
    b		1		标识符
    ;		30		分界符
    }		35		分界符
    printf	1		标识符
    (		26		分界符
    "		36		分界符
    %		45		输出格式符
    "		36		分界符
    ,		32		分界符
    a1		1		标识符
    )		27		分界符
    ;		30		分界符
    return	17		关键字
    0		2		无符号整数
    ;		30		分界符
    }		35		分界符
    

    完整代码: https://download.csdn.net/download/yiwanxianyutang/20089286?spm=1001.2014.3001.5501

    更多相关内容
  • 编译原理实验 词法分析器 语法分析器 完美代码 完美实验
  • C语言语法分析器

    2013-12-15 13:11:55
    编译原理实验课的语法分析器,可以实现基本的语法识别任务,适合计算机科学与技术专业的同学学习分享
  • ),用算符优先分析方法分析表达式是否合法,程序能给出语法分析过程和表达式的结果。由于C语言的运算符较多,导致算符运算关系表比较大,所以每种表达式选择了一种符号作为代表。压缩包中给了多个用例。
  • 通过C语言编写一个语法分析器采用递归下降分析法编写语法分析程序及LL(1)语法分析法编写语法分析程序。附上实验报告。
  • 算符语法分析器,是用C语言编写的,试试看,很不错的
  • 实验一:词法分析器 词法分析器的思路: 1.首先是对关键词的识别 可以做一个数组存放关键词的所有单词,例如下列程序的 char *rwtab[6]={"begin","if","then","while","do","end"}; 2.然后是主程序的逻辑: * 循环...

    实验一:词法分析器

    词法分析器的思路:

    1.首先是对关键词的识别
    可以做一个数组存放关键词的所有单词,例如下列程序的

    char *rwtab[6]={"begin","if","then","while","do","end"};
    

    2.然后是主程序的逻辑:
    * 循环输入缓存中的字母放进输入数组中
    * 调用scaner函数对每一个词进行分析
    * 为数字则拼在一起作为一个数输出
    * 为关键字符或者变量时,拼成字符串输出

    3.scaner函数的思路:
    * token临时数组存放完成后的数字或字符串
    * prog数组存放输入的所有内容
    * p用来保存识别的所有进度,m为token的偏移量,n用来判断是哪个关键词,num用来保存最后的数字
    * 首先初始化token数组
    * 跳过所有空格和回车
    * 先判定字母,然后把数字判断也包含进来,组成了含数字的变量名或者关键词,再判断是不是关键词
    * 再判定数字,最后组成数字
    * 最后是各种符号

    #include <stdio.h>
    #include <string.h>
     
    char prog[80],token[8],ch;  //prog数组用来存放输入的字符串 ,token数组用来存放字符,ch用来表示输入缓存的移动标志 
    int syn,p,m,n,num;//标识码 
    char *rwtab[6]={"begin","if","then","while","do","end"};//关键字数组,由1到6 
    
    void scaner(void);//扫描输入后的字符串,识别关键字、字母和数字 
     
    int main()
    {
    	p=0;                        //用p来表示输入字符串数组的偏移量 
     	printf("\nplease input a string(end with '#'):\n");//提示字符 
     	
     	do{                         //用循环来读取输入缓冲区的字符串 
    	        scanf("%c",&ch);    //读取单个字符 
        		prog[p++]=ch;
    	}while(ch!='#');//用#来表示结束 
     	
     	p=0;
    	do{
    			scaner();
    			switch(syn)//用syn来分辨不同种情况 
    	 		{
    	 			case 11://如果syn是11就是数字 
    	 				printf("< %-5d%8d >\n",syn,num);
    	      		break;
    	      		
    	  			case -1://如果是-1则是错的 
    	  				printf("you have input a wrong string\n");
    	      			//getch(); 
    	      			return 0;
    	      		break;
    	      		
    	  			default://默认就是字符 
    	  			printf("< %-5d%8s >\n",syn,token);
    	      		break;
    	  		}
        	}while(syn!=0);
        //getch();
     }
     
    void scaner(void)
    {  
    	num=0;
    	
        for(m=0;m<8;)
        	token[m++]= NULL;    //初始化token数组 
    	
        ch=prog[p++];      //p从0开始判断 
        m=0;
    		
        while((ch==' ')||(ch=='\n'))        //跳过空格和回车 
    	  		ch=prog[p++]; 
    	
        if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))  //识别字母 
         { 
          	while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9')))//变量名可以含有数字 
          	{
          		token[m++]=ch;
           		ch=prog[p++];
         	}
    		
          	p--;                           //p减一回到上一个字符进行判断 
          	syn=10;
    	  	for(n=0;n<6;n++)               //循环识别关键字 
        	if(strcmp(token,rwtab[n])==0)
           	{ 
           		syn=n+1;                   //由1到6 
            	break;
           	}
         }
    	 else if((ch>='0')&&(ch<='9'))         //识别数字 
         { 
          	while((ch>='0')&&(ch<='9'))
        	{
        		num=num*10+ch-'0';             //将多个单个数字组合成一个数字 
          		ch=prog[p++];
        	}
        	p--;
       		syn=11;
        }
        else                                   //剩下就是各种运算符 
        {
    		switch(ch)
    		{
    		case '<':                           
    			token[m++]=ch;
    			ch=prog[p++];
    			if(ch=='=')                    //识别为小于号 
    			{ 
    				syn=22;
    				token[m++]=ch;
    			}
    			else                           //识别为小于等于号 
    			{  
    				syn=20;
    				p--;
    			}
    		break;
    		case '>':
    			token[m++]=ch;
    			ch=prog[p++];
    			if(ch=='=')                    //识别为大于等于号 
    			{
    				syn=24;
    				token[m++]=ch;
    			}
    			else                           //识别为大于号 
    			{ 
    				syn=23;
    				p--;
    			}
    		break;
     
    		case '+':
    			token[m++]=ch;
    			ch=prog[p++];
    			if(ch=='+')                    //识别为++号 
    			{
    				syn=17;
    				token[m++]=ch;
    			}
    			else                           //识别为+号 
    			{
    				syn=13;
    				p--;
    			}
    		break;
     
    		case '-':                         
    			token[m++]=ch;
    			ch=prog[p++];
    			if(ch=='-')                    //识别为--号 
    			{
    				syn=29;
    				token[m++]=ch;
    			}
    			else                           //识别为-号 
    			{ 
    				syn=14;
    				p--;
    			}
    		break;
     
    		case '!':
    			ch=prog[p++];
    			if(ch=='=')                    //识别为!=号 
    			{ 
    				syn=21;
    				token[m++]=ch;
    			}
    			else                           //识别为错误 
    			{ 
    				syn=31;
    				p--;
    			}
    		break;
     
    		case ':':
    			token[m++]=ch;
    			ch=prog[p++];
    			if(ch=='=')                    //识别为==号 
    			{
    				syn=18;
    				token[m++]=ch;
    			}
    			else                           //识别为=号 
    			{
    				syn=17;
    				p--;
    			}
    		break;
     
    		case '*':                          //识别为* 
    			syn=15;
    			token[m++]=ch;
    		break;
     
    		case '/':                          //识别为/ 
    			syn=16;
    			token[m++]=ch;
    		break;
     
    		case '(':                          //识别为( 
    			syn=27;
    			token[m++]=ch;
    		break;
     
    		case ')':                          //识别为) 
    			syn=28;
    			token[m++]=ch;
    		break;
     
    		case '{':                          //识别为{ 
    			syn=5;
    			token[m++]=ch;
    		break;
     
    		case '}':                          //识别为} 
    			syn=6;
    			token[m++]=ch;
    		break;
     
    		case ';':                          //识别为; 
     			syn=26;
    			token[m++]=ch;
    		break;
     
    		case '\"':                         //识别为” 
    			syn=30;
    			token[m++]=ch;
    		break;
     
    		case '#':                          //识别为# 
    			syn=0;
    			token[m++]=ch;
    		break;
     
     
    		default:                           //识别为错误 
    			syn=-1;
    		break;
    		}
    	}
        	token[m++]='\0';
    }
    

    重要的点

    1. 循环的问题
    for(m=0;m<8;)
        	token[m++]= NULL;
    

    这个位置for循环的第三个参数不要写,有些人习惯就直接写m++。或者可以:

    for(m=0;m<8;m++)
        	token[m]= NULL;
    
    1. 识别字母
    if(ch>='A'&&ch<='z')//当识别字母时可以直接使用这个
    {
    
    }
    

    因为ascii码中字母的顺便是从A~Z a~z变大的,可以一次性整合在一块。

    展开全文
  • 语法分析器的任务主要是确定是否可以以及如何从语法的起始符号推导出输入符号串(输入文本),主要可以通过两种方式完成: 1. 自顶向下分析 根据形式语法规则,在语法分析树的自顶向下展开中搜索输入符号串可能的最...

    语法分析是编译过程的核心部分,其基本任务是根据语言的语法规则进行语法分析,如果不存在语法错误即给出正确的语法结果,并为语义分析和代码生成做准备。

    语法分析器的两种方式

    语法分析器的任务主要是确定是否可以以及如何从语法的起始符号推导出输入符号串(输入文本),主要可以通过两种方式完成:

    1. 自顶向下分析
    根据形式语法规则,在语法分析树的自顶向下展开中搜索输入符号串可能的最左推导。单词按从左到右的顺序依次使用。

    2. 自底向上分析
    语法分析器从现有的输入符号串开始,尝试将其根据给定的形式语法规则进行改写,最终改写为语法的起始符号。

    一、文法G 设计"+ *"检查

    在这里插入图片描述

    二、理论基础

    1. 掌握自上而下语法分析的要求与特点。
    2. 掌握递归下降语法分析的基本原理和方法。
    3. 掌握相应数据结构的设计方法。

    三、代码实现

    #include<stdio.h>
    #include<string.h>
    char Token[30];//存储输入的字符
    char sym;//记录下一个字符
    char s;//输入字符的传递
    static int p=0 ;//下一个字符的下标
    void S();
    void T();
    void U();
    void scaner();//下一个字符
    void error();//错误结束
    int main()
    {
        int i=-1;
        printf("Please input (end with '#'):\n");
        do
        {
            scanf("%c",&s);i++;
    
            Token[i]=s;
        }while(Token[i]!='#');
        scaner();
        S();
        if(sym=='#')
            printf("Success!\n");
        else
            printf("fail!\n");
    
        return 0;
    }
    
    void scaner()
    {
        sym=Token[p];
        p++;
    }
    void error()
    {
        printf("error!");
    }
    void S()
    {
        if(sym=='a'||sym=='^')//如果是a或者是^
            scaner();
        else if(sym=='(')
        {
            scaner();
            T();
            if(sym==')')
                scaner();
            else
                error();
        }
    }
    void T()
    {
        S();
        U();
    }
    
    void U()
    {
        if(sym=='+' || sym=='*' )
        {
            scaner();
            S();
            U();
        }
        else if(sym!=')')
            error();
    }
    

    四、实验结果

    测试用例: ((a+a)*a)#
    在这里插入图片描述

    Ending!!!

    展开全文
  • 语法分析器源代码 C语言

    热门讨论 2011-08-18 22:15:18
    语法分析器源代码 C语言语法分析器源代码 C语言语法分析器源代码 C语言语法分析器源代码 C语言语法分析器源代码 C语言语法分析器源代码 C语言
  • c语言实现词法分析器+文法分析器(全代码)

    学习记录,可能有很多不足,请谅解。

    基本按照教材方法

    在这里插入图片描述
    在这里插入图片描述
    注意本次词法分析只分析上图中拥有的

    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    using namespace std;
    
    string reservewords[] = { "while","if","else","int","print"};//保留字
    char character;//单个字符
    string token;//一串字符
    string yuyan;//语法分析结果
    int numbers[9];//常量储存
    int numberid = 0;
    int wordsid = 0;
    int boolflag;//储存id。转换。
    int boolflag1;
    int boolflag2;
    bool elseflag=false;//判断else是否可执行
    int whileflag=0;//判断while是否可执行
    struct word
    {
    	string name;
    	int value;
    }words[9];//变量储存
    
    bool digit() {//是否为数字
    	return character >= '0' && character <= '9' ? 1 : 0;
    }
    
    void getbe() {//去除空格
    	while (1) {
    		if (character == ' ') {
    			character = getchar();
    		}
    		else {
    			break;
    		}
    	}
    }
    
    bool letter() {//是否为字符
    	return (character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') ? 1 : 0;
    }
    
    void concatenation() {//连接字符串
    	token = token + character;
    }
    
    int reserve() {//判断是否为保留字
    	int id = 0;
    	for (auto s : reservewords) {
    		id++;
    		if (s==token) {
    			return id;
    		}
    	}
    	return 0;
    }
    
    int word() {//判断变量是否存在
    	int id = 0;
    	for (int i = 0; i < 10;i++) {
    		id++;
    		string s = words[i].name;
    		if (s==token) {
    			return id;
    		}
    	}
    	return 0;
    }
    
    int number() {//判断常量是否存在
    	for (int i = 0; i <= numberid;i++) {
    		if (numbers[i]== atoi(token.c_str())) {
    			return i+1;
    		}
    	}
    	return 0;
    }
    
    int main()
    {
    	freopen("chenxu.txt", "r", stdin);//读取土木
    	character = getchar();
    	while (character!=EOF) {//词法分析
    		getbe();
    		if (letter()) {
    			while (letter() || digit()) {
    				concatenation();
    				character = getchar();
    			}
    			boolflag = reserve();
    			if (boolflag!= 0) {
    				yuyan += '_';
    				yuyan += (boolflag + '0');
    				token = "";
    			}
    			else {
    				boolflag = word();
    				if (boolflag != 0) {
    					yuyan += '@';
    					yuyan += (boolflag + '0');
    				}
    				else {
    					words[wordsid].name= token;
    					words[wordsid].value = 0;
    					yuyan += '@';
    					yuyan += ((wordsid+1) + '0');
    					wordsid++;
    				}
    				token = "";
    			}
    		}
    		else if (digit()) {
    			while (digit()) {
    				concatenation();
    				character = getchar();
    			}
    			boolflag = number();
    			if (boolflag != 0) {
    				yuyan += '$';
    				yuyan += (boolflag + '0');
    			}
    			else {
    				int n = atoi(token.c_str());
    				numbers[numberid] = n;
    				yuyan += '$';
    				yuyan += ((numberid + 1) + '0');
    				numberid++;
    			}
    			token = "";
    		}
    		else if (character == '+') {
    			yuyan += character;
    			character = getchar();
    		}
    		else if (character == '-') {
    			yuyan += character;
    			character = getchar();
    		}
    		else if (character == '=') {
    			yuyan += character;
    			character = getchar();
    		}
    		else if (character == '>') {
    			int flag = 0;
    			character = getchar();
    			if (character == '=') {
    				flag = 1;
    				yuyan += '>';
    				yuyan += character;
    				character = getchar();
    			}
    			if (flag == 0) {
    				yuyan += '>';
    			}
    		}
    		else if (character == '<') {
    			yuyan += character;
    			character = getchar();
    		}
    		else if (character == '(') {
    			yuyan += character;
    			character = getchar();
    		}
    		else if (character == ')') {
    			yuyan += character;
    			character = getchar();
    		}
    		else if (character == '{') {
    			yuyan += character;
    			character = getchar();
    		}
    		else if (character == '}') {
    			yuyan += character;
    			character = getchar();
    		}
    		else if (character == ';') {
    			yuyan += character;
    			character = getchar();
    		}
    		else {
    			character = getchar();
    			continue;
    		}
    	}
    	cout << yuyan;
    	cout << endl;
    }
    

    上面是词法分析,下为文法分析,因为文法分析当时只做到了能分析老师给的特定序列并输出结果,所以文法分析存在很多问题,1. if和else依然一对一匹配,但是if和else中间可以穿插其他语句。可以在程序中写判断大小的句子,作为中断判定,如果判断失败,则作为断点中断程序,如果判断成功,就继续程序。while中只能再出现while或一个计算式等

    在代码中添加函数

    
    int bds(int i) {//单个式子文法
    	if (yuyan[i] == '@') {
    		i++;
    		character = yuyan[i];
    		if (digit()) {
    			boolflag = character - '0';
    			i++;
    			character = yuyan[i];
    			if (character == '=')
    			{
    				i++;
    				character = yuyan[i];
    				if (yuyan[i] == '@') {
    					i++;
    					character = yuyan[i];
    					if (digit()) {
    						boolflag1 = character - '0';
    						i++;
    						character = yuyan[i];
    						if (character == '+')
    						{
    							i++;
    							character = yuyan[i];
    							if (yuyan[i] == '$') {
    								i++;
    								character = yuyan[i];
    								if (digit()) {
    									boolflag2 = character - '0';
    									i++;
    									character = yuyan[i];
    									if (character == ';')
    									{
    										words[boolflag - 1].value = words[boolflag1 - 1].value + numbers[boolflag2 - 1];
    										i++;
    										return i;
    									}
    									else {
    										return 0;
    									}
    								}
    								else {
    									return 0;
    								}
    							}
    							else {
    								return 0;
    							}
    						}
    						else if (character == '-') {
    							i++;
    							character = yuyan[i];
    							if (yuyan[i] == '$') {
    								i++;
    								character = yuyan[i];
    								if (digit()) {
    									boolflag2 = character - '0';
    									i++;
    									character = yuyan[i];
    									if (character == ';')
    									{
    										words[boolflag - 1].value = words[boolflag1 - 1].value - numbers[boolflag2 - 1];
    										i++;
    										return i;
    									}
    									else {
    										return 0;
    									}
    								}
    								else {
    									return 0;
    								}
    							}
    							else {
    								return 0;
    							}
    						}
    						else {
    							return 0;
    						}
    					}
    					else {
    						return 0;
    					}
    				}
    			}
    			else if (character == '>') {
    				i++;
    				character = yuyan[i];
    				if (yuyan[i] == '$') {
    					i++;
    					character = yuyan[i];
    					if (digit()) {
    						boolflag1 = character - '0';
    						if (words[boolflag - 1].value > numbers[boolflag1-1]) {
    							i++;
    							return i;
    						}
    						else {
    							return -1;
    						}
    					}
    					else {
    						return 0;
    					}
    				}
    				else if (character == '=') {
    					i++;
    					character = yuyan[i];
    					if (yuyan[i] == '$') {
    						i++;
    						character = yuyan[i];
    						if (digit()) {
    							boolflag1 = character - '0';
    							if (words[boolflag - 1].value >= numbers[boolflag1-1]) {
    								i++;
    								return i;
    							}
    							else {
    								return -1;
    							}
    						}
    						else {
    							return 0;
    						}
    					}
    					else {
    						return 0;
    					}
    				}
    				else {
    					return 0;
    				}
    			}
    			else if (character == '<') {
    				i++;
    				character = yuyan[i];
    				if (yuyan[i] == '$') {
    					i++;
    					character = yuyan[i];
    					if (digit()) {
    						boolflag1 = character - '0';
    						if (words[boolflag - 1].value < numbers[boolflag1-1]) {
    							i++;
    							return i;
    						}
    						else {
    							return -1;
    						}
    					}
    					else {
    						return 0;
    					}
    				}
    				else {
    					return 0;
    				}
    			}
    			else {
    				return 0;
    			}
    		}
    		else {
    			return 0;
    		}
    	}
        else {
             return 0;
        }
    }
    
    int whilesx(int i) {//循环分析
    	int j = i;
    	i++;
    	int aa = bds(i);
    	if (aa > 0) {
    		i = aa;
    		character = yuyan[i];
    		if (character == ')') {
    			i++;
    			character = yuyan[i];
    			if (character == '{') {
    				i++;
    				character = yuyan[i];
    				aa = bds(i);
    				if (aa != 0) {
    					i = aa;
    					if (yuyan[i] == '}') {
    						i++;
    						whileflag = i;
    						i = j;
    						whileflag=whilesx(i);
    					}
    					else {
    						return 0;
    					}
    				}
    				else {
    					if (character == '_') {
    						i++;
    						character = yuyan[i];
    						if (yuyan[i] == '1') {
    							i++;
    							character = yuyan[i];
    							if (yuyan[i] == '(') {
    								whileflag=whilesx(i);
    								i = j;
    								whileflag=whilesx(i);
    							}
    							else {
    								return 0;
    							}
    						}
    						else {
    							return 0;
    						}
    					}
    					else {
    						return 0;
    					}
    				}
    			}
    			else {
    				return 0;
    			}
    		}
    		else {
    			return 0;
    		}
    	}
    	else if (aa == -1) {
    		if (whileflag == 0) {
    			while (yuyan[i] != '}') {
    				i++;
    			}
    			whileflag = i;
    			return whileflag;
    		}
    		else {
    			return whileflag;
    		}
    	}
    	else {
    		return 0;
    	}
    }
    

    在main方法中添加

    for (int i = 0; i < yuyan.length();) {//文法分析,输出结果
    		character = yuyan[i];
    		if (character == '_') {
    			i++;
    			character = yuyan[i];
    			if (character == '1') {
    				i++;
    				character = yuyan[i];
    				if (yuyan[i] == '(') {
    					int aa = whilesx(i);
    					if (aa == 0) {
    						cout << "出错了"; break;
    					}
    					else {
    						while (yuyan[aa] == '}') {
    							aa++;
    						}
    						i = aa;
    					}
    				}
    				else {
    					cout << "出错了"; break;
    				}
    			}
    			else if (character == '2') {
    				elseflag = false;
    				i++;
    				character = yuyan[i];
    				if (yuyan[i] == '(') {
    					i++;
    					int aa = bds(i);
    					if (aa > 0) {
    						elseflag = false;
    						i = aa;
    						character = yuyan[i];
    						if (character == ')') {
    							i++;
    							character = yuyan[i];
    							if (character == '{') {
    								i++;
    								character = yuyan[i];
    								aa = bds(i);
    								if (aa != 0) {
    									i = aa;
    									if (yuyan[i] == '}') {
    										i++;
    										continue;
    									}
    									else {
    										cout << "出错了"; break;
    									}
    								}
    								else {
    									cout << "出错了"; break;
    								}
    							}
    							else {
    								cout << "出错了"; break;
    							}
    						}
    						else {
    							cout << "出错了"; break;
    						}
    					}
    					else if (aa == -1) {
    						elseflag = true;
    						while (yuyan[i] != '}') {
    							i++;
    						}
    						i++;
    					}
    					else {
    						cout << "出错了"; break;
    					}
    				}
    				else {
    					cout << "出错了"; break;
    				}
    			}
    			else if (character == '3') {
    				if (elseflag == false) {
    					while (yuyan[i] != '}') {
    						i++;
    					}
    					i++;
    				}
    				else {
    					i++;
    					character = yuyan[i];
    					if (yuyan[i] == '{') {
    						i++;
    						character = yuyan[i];
    						int aa = bds(i);
    						if (aa != 0) {
    							i = aa;
    							if (yuyan[i] == '}') {
    								i++;
    								continue;
    							}
    							else {
    								cout << "出错了"; break;
    							}
    						}
    						else {
    							cout << "出错了"; break;
    						}
    					}
    					else {
    						cout << "出错了"; break;
    					}
    				}
    			}
    			else if (character == '4') {
    				i++;
    				character = yuyan[i];
    				if (yuyan[i] == '@') {
    					i++;
    					character = yuyan[i];
    					if (digit()) {
    						boolflag = character - '0';
    						i++;
    						character = yuyan[i];
    						if (character == '=')
    						{
    							i++;
    							character = yuyan[i];
    							if (yuyan[i] == '$') {
    								i++;
    								character = yuyan[i];
    								if (digit()) {
    									boolflag1 = character - '0';
    									i++;
    									character = yuyan[i];
    									if (character == ';')
    									{
    										words[boolflag - 1].value = numbers[boolflag1 - 1];
    										i++;
    									}
    									else {
    										cout << "出错了";
    										break;
    									}
    								}
    								else {
    									cout << "出错了";
    									break;
    								}
    							}
    							else {
    								cout << "出错了";
    								break;
    							}
    						}
    						else {
    							cout << "出错了";
    							break;
    						}
    					}
    					else {
    						cout << "出错了";
    						break;
    					}
    				}
    				else {
    					cout << "出错了";
    					break;
    				}
    			}
    			else if (character == '5') {
    				i++;
    				character = yuyan[i];
    				if (yuyan[i] == '@') {
    					i++;
    					character = yuyan[i];
    					if (digit()) {
    						boolflag = character - '0';
    						i++;
    						character = yuyan[i];
    						if (character == ';')
    						{
    							cout << words[boolflag - 1].value;
    							i++;
    						}
    						else {
    							cout << "出错了";
    							break;
    						}
    					}
    					else {
    						cout << "出错了";
    						break;
    					}
    				}
    				else {
    					cout << "出错了";
    					break;
    				}
    			}
    			else { cout << "出错了"; break; }
    		}
    		else if (character == '@') {
    			i = bds(i);
    			if (i == 0) {
    			cout << "出错了"; break;
    			}
    			if(i==-1){
    				cout << "程序中断退出"; break;
    			}
            }
            else {
                cout << "出错了"; break;
    	    }
    	}
    

    结果展示

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

    感谢观看

    展开全文
  • 安装Java的: 您可以参考安装指南。 要检查是否已安装Java: $ java -version$ javac -versionAntlr: 请访问主网站。您可以找到如何在Linux,OS X,Windows上安装。 PS:确保在源文件中放入以下行(.bashrc,.zshrc...
  • 这是编译原理我自己做的语法分析,读取字符流文件分析出各种语法成分,也可以把他改成词法分析器。易读
  • 算符优先语法分析器C语言编写

    热门讨论 2009-05-17 23:08:29
    这是一个由C语言编写语法分析器,采用算符优先算法,source文件中读取算符优先分法后构造FIRSTVT和LASTVT集,并构造优先关系表,最有打印详细规约过程。
  • 编译原理课程上要求自己完成一个简单的词法分析器C语言搞定,思路简单清晰。
  • 用java语言编写的词法分析器、语法分析器和语义分析器,已经内置了静态的基本语言,通过文件读入代码,上传供各位学习交流使用。
  • (使用Python实现,注释详尽)在词法分析器的基础上,采用递归下降的方法实现算术表达式的语法分析器,以加深对自上而下语法分析过程的理解。 1、对算术表达式文法: E→TE' E'→+TE'| -TE' |ε T→FT' T'→*FT'| /...
  • C语言编写一个C语言源程序的词法分析器(标题收回) 2.要求 [1] 基本要求:识别关键字、运算符、界限符、常量(布尔型、整型)、标识符; [2] 扩展要求:常量(浮点型)、注释、错误处理。 3.对照表 ...
  • 自己实现的编译原理的LL1语法分析器,是自己的实验作业,用Vs2017实现,可以直接运行,代码注释丰富,希望与大家交流学习!欢迎大家下载!
  • 编写一个语法分析程序,对于给定的输入串,能够判断识别该串是否为给定文法的句型。输入一个LL(1)文法,构造相应的LL(1)预测分析表。2.从键盘读入输入串,由算法判断该输入串是否为该文法的句子,若正确,就...
  • Bison语法分析器-2

    2020-05-05 10:14:20
    建议只做参考使用,请勿抄袭 利用附录提供的C语言文法的相关参考资料,...利用语法分析器生成工具 Bison 编写一个语法分析程序,与词法分析器结合,能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子。
  • 3. 掌握词法分析器的设计与调试。二、实验内容根据编译中的分词原理,用C++语言编写一个C语言的词法分析程序:.三、实验要求1. 输入:任意一个C语言程序的源代码。2. 处理:对输入进行分析,分离出保留字、标识符、常量、...
  • C语言编写一个PL/0词法分析器,为语法语义分析提供单词,使之能把输入的字符串形式的源程序分割成一个个单词符号传递给语法语义分析,并把分析结果(基本字,运算符,标识符,常数以及界符)输出。(含实验报告,cpp...
  • 递归下降语法分析器

    2019-05-08 16:22:34
    c语言编写的递归下降语法分析器的算法,测试成功可以直接跑代码
  • 编译原理/基于C语言的词法分析器,输入输出皆采用文件方式,输入txt文件包括测试程序,输出txt包括程序的词法分析
  • 语法分析(C语言编写)

    2009-05-12 14:34:46
    C语言编写语法分析器,计算机专业的作业,需要的下载吧;
  • 基于c语言语法分析器的实现

    万次阅读 2016-10-20 09:53:03
    一. 总体实现思想 我采用自顶向下的预测...具体的非递归的预测语法分析结构如下所示: 非递归的预测分析不需要为每个非终结符编写递归下降过程,而是根据预测分析表构造一个自动机,也叫表驱动的预测分析 表驱动
  • 3、编写的分析程序能够对实验一的结果进行正确的语法分析;4、对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利完成语法分析过程;三、实验指导(一)准备1.阅读课本有关章节,。2.初步编制...
  • c语言设计的词法分析器 做编译原理实验的福音
  • 编译原理实验三,PL0语言语法分析器,含详细注释,文件顶部有教学文档,打开即用。C++/C语言
  • 用C++编写的类C语言编译器,代码清晰。完成词法分析、语法分析LR1、语义分析。其中LR语法分析自动生成action-goto表。语义分析生成三地址码。可做编译原理课程设计大作业等等。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 36,649
精华内容 14,659
关键字:

语法分析器c语言编写