zoukankan      html  css  js  c++  java
  • 1231-递归下降语法分析

    #include<stdio.h> 
    #include<malloc.h>   
    #define READ(ch) ch=getc(fp) /*宏:READ(ch)*/  
    char  ch;      /*声明为全局变量*/ 
    int  right=0;   
    FILE *fp;
    struct struCH
    {  
        char ch;   
        struct struCH *next; 
    }struCH,*temp,*head,*shift;  
    /*head指向字符线性链表的头结点*/ 
    /*shift指向动态建成的结点(游标)*/  
    
    void main(int argc,char *argv[])
    {  
        void E ();  /* P(E) */  
        void E1(); /* P(E')*/  
        void T ();  /* P(T) */  
        void T1(); /* P(T')*/  
        void F ();  /* P(F) */     
        
        
        int errnum=0,k=0,m=0,countchar=0,rownum;  
        int charerr=0; /*开关控制量*/     
        
        /************************以只读方式打开文件*********************/     
        if((fp=fopen(argv[1],"r"))==NULL)   
        {  
            printf("
    	Can not open file %s,or not exist it!
    ",argv[1]);   
            exit(0);      /*文件不存在or打不开时,正常退出程序*/  
        }   
        else 
            printf("
    	Success open file: %s
    ",argv[1]); /*成功打开文件*/      
        
        /******************遍历整个文件检测是否有非法字符********************/     
        
        /*如果用while(!feof(fp))语言,将会多出一个字符    
         *所以这里采用以下方法遍历整个文件检测其否有非法字符  
        */    
        
        /*[1]计算文件中字符数量*/ 
        while(!feof(fp))
        {   
            READ(ch);   /*这里读取字符只是让文件指针往前移*/   
            countchar++;   /*统计文件中的字符数(包括换行符及文件结束符)*/  
        }   
        rewind(fp);    /*将fp文件指针重新指向文件头处,以备后面对文件的操作*/  
        if(countchar==0)
        {   /*空文件*/   
            printf("	%s is a blank file!
    ",argv[1]);    
            exit(0);    /*正常退出本程序*/  
        }
        /*[2]开始遍历文件*/   
        while(k<(countchar-1))
        {      /*加换行符后countchar仍多了一个,不知为何*/   
               ch=getc(fp);      
               if(!(ch=='('||ch==')'||ch=='i'||ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='#'||ch=='
    '))
               {    
                   charerr=1;errnum++;      /*charerror出错标记,errnum统计出错个数*/   
               }  
               k++;   
        }  
        rewind(fp);  /*将fp文件指针重新指向文件头处,以备后面的建链表操作*/                                                  
        if(charerr==1)                                             
        { /*文件中有非法字符*/                                               
            printf("
    	%d Unindentify characters in file %s 
    ",errnum,argv[1]);                                           
            exit(0);   /*正常退出本程序*/                                                              
        }     
                                                                      
                                                                      
                                                                     
        /*******************非空且无非法字符,则进行识别操作*****************/                                          
        for(rownum=1;m<(countchar-1);rownum++)
        { 
            /*识别所有行,rownum记录行号*/   
            /*初始变量及堆栈和*/   
            right=1;   
            
            /*初始存放待识别的表达式的线性链表头*/  
            shift=malloc(sizeof(struCH));
            shift->next=NULL;  
            head=shift;   
            
            /*读取一行形成线性链表*/   
            READ(ch);
            putchar(ch);
            m++;   
            while(ch!='
    '&&m<(countchar))
            {
                /*行末or到文件尾。最后会读取文件结束符*/
                /*读取ch,读取存入结点,这样每行便形成一个线性链表*/    
                temp=malloc(sizeof(struCH));   
                temp->ch=ch;    
                temp->next=NULL; 
                shift->next=temp;   
                shift=shift->next;   
                READ(ch);  
                if(m!=(countchar-1)) 
                    putchar(ch); 
                /*不输出最后一次读取的文件结束符*/   
                m++;   
            }  
            head=head->next; /*消去第一个空头结点,并使head指向非空线性链表头*/   
            shift=head;     /*shift指向头结点,以便后面识别操作*/   
            putchar('
    ');  
            E();       /*开始识别一行*/     
            if(shift->ch=='#'&&right) /*正确提示:[文件名] Line [行号]:right expression!*/   
                printf("%s  Line %d:	 right expression!
    ",argv[1],rownum);   
            else       /*错误提示:[文件名] Line [行号]:error expression!*/    
                printf("%s  Line %d:	 error expression!
    ",argv[1],rownum);    
            putchar('
    ');  
        }/*end for*/  
        printf("Completed!
    ");  
        fclose(fp); /*关闭文件*/  
        exit(0);  /*正常结束程序*/
    }    
    
    
    /*以下函数分别对应于子模块程序*/    
    void E()
    {  
        T();
        E1(); 
    }  
    
     
    void E1()
    {   
        if(shift->ch=='+'||shift->ch=='-')
        {   
            shift=shift->next;   
            T();  
            E1();  
        }  
        else
        { 
            if(shift->ch=='#'||shift->ch==')')    
                return; 
            else  
                right=0; 
        } 
    }   
    
    void T(void)
    {   
        F();  
        T1(); 
    }   
    
    void T1(void)
    {    
        if(shift->ch=='*'||shift->ch=='/')
        {  
            shift=shift->next;   
            F();  
            T1(); 
        } 
        else
        {   
            if(shift->ch!='#'&&shift->ch!=')'&&shift->ch!='+'&&shift->ch!='-')    
                right=0; /*如果不是'#'or')'or'+'or'+'or'-'则出错*/  
        }
    } 
    
      
    void F(void)
    {  
        if(shift->ch=='i')   
            shift=shift->next;  
        else
        {   
            if(shift->ch=='(')
            {    
                shift=shift->next;    
                E();   
                if(shift->ch==')')    
                    shift=shift->next;   
                else   
                    right=0;  
            }  
            else   
                right=0;  
        } 
    }
  • 相关阅读:
    1022.游船出租
    1021.统计字符
    1020.最小长方形
    1017.还是畅通工程
    1019.简单计算器
    1015.还是A+B
    1014.排名
    1013.开门人和关门人
    1011.最大连续子序列
    1009.二叉搜索树
  • 原文地址:https://www.cnblogs.com/wangzekai/p/5090269.html
Copyright © 2011-2022 走看看