编译原理 之 语法分析器(自上而下分析法)

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define fprint(fpw,k) { if(k>='a'&&k<='z') fprintf(fpw,"%c",k); else fprintf(fpw,"temp%d",k); }

int PLACE=1;
int index=1;

typedef struct _info{
    int place;
    int op;
}info;

int advance(FILE *fpr)
{
    char t;
    t=fgetc(fpr);
    if(t==EOF)
        return '#';
    return t;
}

int E(FILE *fpr,FILE *fpw,int *character,info *k);
int V(FILE *fpr,FILE *fpw,int *character,info *k)
{
    int flag=0;
    if(*character>='a'&&*character<='z')
        flag=1;
    if(flag==0)
    {
        printf("error in V!\n");
        return 0;
    }
    k->place=*character;
    *character=advance(fpr);
    return 1;
}

int F(FILE *fpr,FILE *fpw,int *character,info *k)//F=(E)|V
{
    info v;
    v.place=0;
    if(*character=='(')
    {
        *character=advance(fpr);
        if(E(fpr,fpw,character,&v)==0)
            return 0;
        if(*character!=')')
        {
            printf("error in F!\n");
            return 0;
        }
        *character=advance(fpr);
    }
    else
    {
        if(V(fpr,fpw,character,&v)==0)
            return 0;;

    }
    k->place=v.place;
    return 1;
}

int T1(FILE *fpr,FILE *fpw,int *character,info *k)// T1=(*|/)F T1
{
    info f,t1;
    f.place=t1.place=0;
    if(*character=='*'||*character=='/')
    {
        if(*character=='*')
            k->op=0;
        else
            k->op=1;
        *character=advance(fpr);
        if(F(fpr,fpw,character,&f)==0)
            return 0;
        if(T1(fpr,fpw,character,&t1)==0)
            return 0;
        if(t1.place==0)
            k->place=f.place;
        else
        {
            k->place=PLACE++;
            fprintf(fpw,"%3d: ",index++);
            fprintf(fpw,"'%c',",t1.op==0?'*':'/');
            fprint(fpw,f.place);
            fprintf(fpw,",");
            fprint(fpw,t1.place);
            fprintf(fpw,",");
            fprint(fpw,k->place);
            fprintf(fpw,"\n");
        }
    }
    return 1;
}

int T(FILE *fpr,FILE *fpw,int *character,info *k)// T=F T1
{
    info f,t1;
    f.place=t1.place=0;
    if(F(fpr,fpw,character,&f)==0)
        return 0;
    if(T1(fpr,fpw,character,&t1)==0)
        return 0;
    if(t1.place==0)
        k->place=f.place;
    else
    {
        k->place=PLACE++;
        fprintf(fpw,"%3d: ",index++);
        fprintf(fpw,"'%c',",t1.op==0?'*':'/');
        fprint(fpw,f.place);
        fprintf(fpw,",");
        fprint(fpw,t1.place);
        fprintf(fpw,",");
        fprint(fpw,k->place);
        fprintf(fpw,"\n");
    }
    return 1;
}

int E1(FILE *fpr,FILE *fpw,int *character,info *k)// E1=(+|-)T E1
{
    info t,e1;
    t.place=e1.place=0;
    if(*character=='+'||*character=='-')
    {
        if(*character=='+')
            k->op=0;
        else
            k->op=1;
        *character=advance(fpr);
        if(T(fpr,fpw,character,&t)==0)
            return 0;
        if(E1(fpr,fpw,character,&e1)==0)
            return 0;
        if(e1.place==0)
            k->place=t.place;
        else
        {
            k->place=PLACE++;
            fprintf(fpw,"%3d: ",index++);
            fprintf(fpw,"'%c',",e1.op==0?'+':'-');
            fprint(fpw,t.place);
            fprintf(fpw,",");
            fprint(fpw,e1.place);
            fprintf(fpw,",");
            fprint(fpw,k->place);
            fprintf(fpw,"\n");
        }
    }
    return 1;
}

int E(FILE *fpr,FILE *fpw,int *character,info *k)// E=T E1
{
    info t,e1;
    t.place=e1.place=0;
    if(T(fpr,fpw,character,&t)==0)
        return 0;
    if(E1(fpr,fpw,character,&e1)==0)
        return 0;
    if(e1.place==0)
        k->place=t.place;
    else
    {
        k->place=PLACE++;
        fprintf(fpw,"%3d: ",index++);
        fprintf(fpw,"'%c',",e1.op==0?'+':'-');
        fprint(fpw,t.place);
        fprintf(fpw,",");
        fprint(fpw,e1.place);
        fprintf(fpw,",");
        fprint(fpw,k->place);
        fprintf(fpw,"\n");
    }
    return 1;
}

int A(FILE *fpr,FILE *fpw,int *character)// V=E
{
    info e,v;
    e.place=v.place=0;
    if(V(fpr,fpw,character,&v)==0)
        return 0;
    if(*character!='=')
    {
        printf("error in A!\n");
        return 0;
    }
    *character=advance(fpr);
    if(E(fpr,fpw,character,&e)==0)
        return 0;
    fprintf(fpw,"%3d: ",index++);
    fprintf(fpw,"'=',");
    fprint(fpw,e.place);
    fprintf(fpw,",-,");
    fprint(fpw,v.place);
    fprintf(fpw,"\n");
    return 1;
}

void scan(FILE *fpr,FILE *fpw)
{
    int character;
    index=1;
    PLACE=1;
    character=advance(fpr);
    if(A(fpr,fpw,&character)==0)
        return;
    printf("succeed!\n");
}

int main()
{
    int n;
    system("color 1E");
    FILE *fpr,*fpw;
    char filepath[256];
    while(1)
    {
    printf("选择文件输入的请按 1,结束请 2!\n");
    scanf("%d",&n);
    switch(n)
    {
        case 1:
    {
    A: printf("请输入源文件路径: ");
    scanf("%s",filepath);
    fpr=fopen(filepath,"rt");
    if(fpr==NULL)
    {
        printf("打开源文件失败!\n");
        goto A;
    }
    putchar(10);
    B:printf("请输入输出文件路径: ");
    scanf("%s",filepath);
    fpw=fopen(filepath,"wt");
    putchar(10);
    if(fpw==NULL)
    {
        printf("创建目标文件失败!\n");
        goto B;
    }
    scan(fpr,fpw);
    fclose(fpr);
    fclose(fpw);
    fpw=fopen(filepath,"rt");
    char ch;
    while(!feof(fpw))
    {
        ch=fgetc(fpw);
        printf("%c",ch);
    }
    fclose(fpw);
    break;
    }

    case 2:
    {
      printf("谢谢使用!\n\n\n");
      system("pause");
      return 0;
    }
    default: printf("输入数字错误,请重新输入数字:!\n\n\n");
    }
    }
    return 0;
}

递归下降分析法 一、实验目: 根据某一文法编制调试递归下降分析程序,以便对任意输入符号串进行分析。本次实验主要是加深对递归下降分析法理解。 二、实验说明 1、递归下降分析法功能 词法分析器功能是利用函数递归调用模拟语法树自上而下构造过程。 2、递归下降分析法前提 改造文法:消除二义性、消除左递归、提取左因子,判断是否为LL1文法, 3、递归下降分析法实验设计思想及算法 为G每个非终结符号U构造一个递归过程,不妨命名为U。 U产生式右边指出这个过程代码结构: (1)若是终结符号,则和向前看符号对照, 若匹配则向前进一个符号;否则出错。 (2)若是非终结符号,则调用与此非终结符对应过程。当A右部有多个产生式时,可用选择结构实现。 三、实验要求 准备: 1.阅读课本有关章节, 2.考虑好设计方案; 3.设计出模块结构、测试数据,初步编制好程序。 上课上机: 将源代码拷贝到机上调试,发现错误,再修改完善。第二次上机调试通过。 程序要求: 程序输入/输出示例: 对下列文法,用递归下降分析法对任意输入符号串进行分析: 1E->eBaA 2A->a|bAcB 3B->dEd|aC 4C->e|dc 输出格式如下: (1)递归下降分析程序,编制人:姓名,学号,班级 (2)输入一以#结束符号串:在此位置输入符号串例如:eadeaa# (3)输出结果:eadeaa#为合法符号串 注意: 1.如果遇到错误表达式,应输出错误提示信息该信息越详细越好; 2.对学有余力同学,可以详细输出推导过程,即详细列出每一步使用产生式。 程序思路 0.定义部分:定义常量、变量、数据结构。 1.初始化:从文件将输入符号串输入到字符缓冲区中。 2.利用递归下降分析法分析,对每个非终结符编写函数,在主函数中调用文法开始符号函数。
相关推荐
这个里面都是测试数据,总共得分5分。从控制台输入,不能从文件中读取。实现了基本功能,加分项目都没有去实现,没有函数数组这些实现。这是用C++语言写,新建parser类别要选C++,其他对于VS配置和C语言一样。for语句用是枚举所有情况,你可以自行修改。 对预备工作中自然语言描述简化C编译器语言特性语法,设计上下文无关文法进行描述 借助Yacc工具实现语法分析器 考虑语法树构造: 1.语法树数据结构设计:节点类型设定,不同类型节点应保存哪些信息,多叉树实现方式 2.实现辅助函数,完成节点创建、树创建等功能 3.利用辅助函数,修改上下文无关文法,设计翻译模式 4.修改Yacc程序,实现能构造语法树分析器 考虑符号表处理扩充 1.完成语法分析后,符号表项应增加哪些标识符属性,保存语法分析结果 2.如何扩充符号表数据结构,Yacc程序如何与Lex程序交互,正确填写符号表项 以一个简单C源程序验证你语法分析器,可以文本方式输出语法树结构,以节点编号输出父子关系,来验证分析器正确性,如下例: main() { int a, b; if (a == 0) a = b + 1; } 可能输出为: 0 : Type Specifier, integer, Children: 1 : ID Declaration, symbol: a Children: 2 : ID Declaration, symbol: b Children: 3 : Var Declaration, Children: 0 1 2 4 : ID Declaration, symbol: a Children: 5 : Const Declaration, value:0, Children: 6 : Expr, op: ==, Children: 4 5 7 : ID Declaration, symbol: a Children: 8 : ID Declaration, symbol: b Children: 9 : Const Declaration, value:1, Children: 10: Expr, op: +, Children: 8 9 11: Expr, op: =, Children: 7 10 12: if statement, Children: 6 11 13: compound statement, Children: 3 12
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:白松林 返回首页