语法分析实验部分简易版

来源:互联网 发布:5g网络架构 杨峰义pdf 编辑:程序博客网 时间:2024/06/05 22:58

代码是从清华那本编译教材后边实验部分改的
二、实验内容
“简单的算法表达式文法”
〈算术表达式〉∷=〈项〉│〈算术表达式〉+〈项〉│〈算术表达式〉-〈项〉
〈项〉∷=〈因式〉│〈项〉*〈因式〉│〈项〉/〈因式〉
〈因式〉∷=〈变量〉│(〈算术表达式〉)
〈变量〉∷=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
说明:为了简化变量,即简化词法分析程序,此文法中变量的定义就是一个字母。

根据“简单的算法表达式文法”在starter files基础上编写一个递归向下的语法分析程序。
输入:字符串或者文本文件
输出:“合法表达式”或者“非法表达式”
例如:输入a+b*c-b/d则显示或者输出“合法表达式”,输入aa++–c*则显示或者输出“非法表达式”

三、实验分析与设计
S: 算术表达式
B: 项
C: 因式
D: 变量
消除左递归后的文法:
S->BI
I->+BI|-BI|ξ
B->CJ
J->*BI|/BI|ξ
C->D|(S)
D->a|…|z
First(S)={a,…,z,(}
First(I)={+,-, ξ}
First(B)={a,…,z,(}
First(J)={*,/, ξ}
First(C)={a,…,z,(}
First(D)={a,…,z}

Follow(S)={#,)}
Follow(B)={+,-,),#}
Follow(I)={#,)}
Follow(J)={+,-,),#}
Follow(C)={*,/,+,-,),#}
Follow(D)={*,/,+,-,),#}

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>/* 符号 */enum symbol       //枚举类型{    nul, end, ident, plus, times, lparen, divide, rparen, sub,};#define al 10          //标识符的最大长度enum symbol sym;    //当前的符号char ch;              //获取当前字符,getch 使用char a[al+1];         //当前标识符identFILE* fin;            //用于指向输入文件的指针void getsym();      //读单词,将单词类别放入sym中void S();void I();void B();void J();void C();void D();int main(){    char filename[20];     //文件名数组    printf("请输入分析的文件名:");    gets(filename);    //scanf("%s",filename);    do    {        if((fin=fopen(filename,"r"))==NULL)        //以只读方式打开文件,并判断输入文件名是否正确        {            printf("不能打开文件.\n");            return 0;        }        getsym();            //读第一个单词,将单词类别放入sym中        S();                //开始按E->TA  分析        if (sym==end)        {            printf("语法正确\n");        }        else        {            printf("语法错\n");        }        fclose(fin);         //关闭文件        printf("继续分析则输入文件名,否则回车");        //scanf("%s",filename);        gets(filename);    }    while (strlen(filename)>0);      //判断文件名字符串是否大于0}/*词法分析,获取一个符号*/void getsym(){    ch=fgetc(fin);    while (ch==' ' || ch==10 || ch==13 || ch==9)  /* 忽略空格、换行、回车和TAB */        ch=fgetc(fin);    if (ch==EOF)  sym=end;    else if (ch>='a' && ch<='z')        sym = ident;    else if(ch == '+')        sym = plus;    else if (ch == '*')        sym = times;    else if (ch == '/')        sym = divide;    else if (ch == '-')        sym = sub;    else if (ch == '(')        sym = lparen;    else if (ch == ')')        sym = rparen;    else    {       sym = nul;        printf("--词法错\n");        exit(0);    }    return;}//递归下降分析  分析产生式E->  TAvoid  S(){    if (sym==ident ||sym==lparen)       //如果类型是标识符(变量)或者左括号    {        B();           //先按B推导,执行B        I();           //再按I推导,执行I    }    else    {        printf("语法错: 缺变量或者左括号\n");        exit(0);    }}void D(){    if (sym==ident)          //当前单词为indent(标识符)类型        getsym();        //读下一个单词    else    {        printf("语法错: 缺变量\n ");        exit(0);    }}//添加void I(){    if(sym==plus||sym==sub)     //如果类型是加或者减    {        getsym();           //读下一个单词        B();                //调用执行B        I();                //调用执行I    }    else if(sym==rparen  || sym==end)//右括号或者文件结束    {        return;    }    else    {        if(sym==nul)        {            printf("错误4:非法操作符\n");            exit(0);        }        else        {            printf("错误5:缺少操作符+或者缺少操作符-");            exit(0);        }    }}void B(){    C();                        //调用执行C    J();                        //调用执行J}void J(){    if(sym==times||sym==divide)     //如果类型是*或者除法    {        getsym();           //读取下一个单词        C();                //调用执行C        J();                //调用执行J    }    else if(sym==plus || sym==sub || sym==rparen || sym==end)//+——)或者结束    {        return;    }    else    {        if(sym==nul)        {            printf("错误4:非法操作符\n");            exit(0);        }        else        {            printf("错误6:缺少操作符×或者÷\n");            exit(0);        }    }}void C(){    if(sym==lparen)           //如果类型是左括号    {        getsym();            //读取下一个单词        S();                  //调用执行S        if(sym==rparen)     //如果类型是右括号        {            getsym();   //读取下一个单词            return;        }        else        {            printf("语法错: 缺变量或符号\n ");            exit(0);        }    }    else    {        D();                //否则调用执行D    }}

五、运行的结果
懒得贴的还要截图 反正可以正经运行