• 1231实验四 递归下降语法分析程序设计


    #include<stdio.h>
    #include<stdlib.h>
    #include<malloc.h>
    #define READ(ch) ch=getc(fp)
    char ch;
    int right=0;
    FILE *fp;
    struct struCH
    {
    char ch;
    struct struCH *next;
    }struCH,*temp,*head,*shift;
    /*head指向字符线性链表的头结点*/
    /*shift指向动态建成的结点(游标)*/
    void E ();
    void E1();
    void T ();
    void T1();
    void F ();
    void main(int argc,char *argv[])
    {
    void E ();
    void E1();
    void T ();
    void T1();
    void 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]); /*成功打开文件*/
    /*[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;
    }
    }

  • 相关阅读:
    IE6下实现Width:auto
    Dynamic Linq 的Like扩展
    用一句JQuery代码实现表格的简单筛选
    jquery:利用jsonp跨域访问转载
    LINQ动态组合查询
    Windows服务中Timer组件
    正则表达式笔记转载
    继LINQ动态组合查询PredicateExtensions讲解
    错误笔记:在OleDb执行下Access ,程序不报错,但是Update也更新不成功的
    jQuery 1.4 版本的十五个新特性转载
  • 原文地址:https://www.cnblogs.com/88mei/p/5091911.html
Copyright © 2020-2023  润新知