• 编译原理实验之SLR1文法分析


    ---内容开始---

    这是一份编译原理实验报告,分析表是手动造的,可以作为借鉴。

    基于  SLR(1) 分析法的语法制导翻译及中间代码生成程序设计原理与实现
    1 、理论传授
    语法制导的基本概念,目标代码结构分析的基本方法,赋值语句语法制导生成四元式的
    基本原理和方法,该过程包括语法分析和语义分析过程。


    2 、目标任务
    [ 实验 项目] 完成以下描述赋值语句 SLR(1)文法语法制导生成中间代码四元式的过程。
    G[A]:A→V=E
    E→E+T∣E-T∣T
    T→T*F∣T/F∣F
    F→(E)∣i
    V→i
     [ 设计说明 ] 终结符号 i 为用户定义的简单变量,即标识符的定义。
     [ 设计要求] 

    (1)构造文法的 SLR(1)分析表,设计语法制导翻译过程,给出每一产生式
    对应的语义动作;

    (2)设计中间代码四元式的结构;

    (3)输入串应是词法分析的输出二元式序列,即某赋值语句“专题 1”的输出结果,输出为赋值语句的四元式序列中间文件;

    (4)设计两个测试用例(尽可能完备),并给出程序执行结果四元式序列。
     

    3、 程序功能描述

    在第一次实验词法分析输出结果的基础上设计SLR1文法分析过程,并了解四元式的形成:

    1. 输入串为实验一的二元式序列
    2. 输出为对输入串的SLR(1)文法的判断结果
    3. 输出有针对输入串的SLR(1)文法的具体分析过程
    4. 有对输入串的四元式输出序列

    4、 主要数据结构描述

    二元组结构体,用来存储词法分析程序输出的二元组对 <类别,单词>:

    int count;

    struct eryuanzu

    {

    int a;

    char temp[COUNT];

    }m[COUNT];

     

    void out(int a,char* temp){// 打印二元组

     

    printf("< %d %s > ",a,temp);

    m[count].a=a;

    strcpy(m[count].temp,temp);  //

    count++;

    }

     

    SLR1分析过程中所要用到的状态栈、符号栈等:

     

    stack<int> state;           //状态栈

    stack<char> sign;           //符号栈

    char st; //规约弹出时,状态栈顶元素

    int flag=0; //标志是否是SLR

    stack<string> place;        //变量地址栈

    ACTION表,二维数组表示:

    /* i  ( ) + - * / =  #

    1开头的百位数为s移进项,0error-1accept,其余的一位两位数是r规约项*/

    int ACTION[20][9]={{103,0,0,0,0,0,0,0,0},//0

    {0,0,0,0,0,0,0,0,-1},

    {0,0,0,0,0,0,0,104,0},

    {0,0,0,0,0,0,0,10,0},                                           

    {109,108,0,0,0,0,0,0},

    {0,0,0,110,111,0,0,0,1},//5 mnl;;huhyhjhjio

    {0,0,4,4,4,112,113,0,4},

    {0,0,7,7,7,7,7,0,7},

    {109,108,0,0,0,0,0,0,0},

    {0,0,9,9,9,9,9,0,9},

    {109,108,0,0,0,0,0,0,0},//10

    {109,108,0,0,0,0,0,0,0},

    {109,108,0,0,0,0,0,0,0},

    {109,108,0,0,0,0,0,0,0},

    {0,0,119,110,111,0,0,0,0},

    {0,0,2,2,2,112,113,0,2},//

    {0,0,3,3,3,112,113,0,3},

    {0,0,5,5,5,5,5,0,5},

    {0,0,6,6,6,6,6,0,6},

    {0,0,8,8,8,8,8,0,8}};//19

     

    ·GOTO表,二维数组表示:

    //A V E T F

    int GOTO[20][5]={{1,2,0,0,0},

    {0,0,0,0,0},//1

    {0,0,0,0,0},

    {0,0,0,0,0},

    {0,0,5,6,7},

    {0,0,0,0,0},//5

    {0,0,0,0,0},

    {0,0,0,0,0},

    {0,0,14,6,7},

    {0,0,0,15,7},

    {0,0,0,16,7},//10

    {0,0,0,0,17},

    {0,0,0,0,18},

    {0,0,0,0,0},

    {0,0,0,0,0},

    {0,0,0,0,0},//15

    {0,0,0,0,0},

    {0,0,0,0,0},

    {0,0,0,0,0},

    {0,0,0,0,0}};//19

     

    规约时所用到的函数,分别对应每一条规则:

    void R1();          //AV=E

    void R2();          //EE+T

    void R3();          //EE-T

    void R4();          //ET

    void R5();          //TT*F

    void R6();          //TT/F

    void R7();          //TF

    void R8();          //F(E)

    void R9();          //Fi

    void R10();         //Vi

     

    void R1() {

     

     

     

    sign.pop(); sign.pop(); sign.pop();       //弹出符号栈

     

    state.pop(); state.pop(); state.pop();    //弹出状态栈

     

    sign.push('A');                         //符号'A'入栈

     

    st=state.top();

     

    printf("r1 ");

     

    }

     

    void R2() {

     

     

     

    sign.pop(); sign.pop(); sign.pop();       //弹出符号栈

     

    state.pop(); state.pop(); state.pop();    //弹出状态栈

     

    sign.push('E'); st=state.top();                        //符号'E'入栈

     

    printf("r2 ");

     

    }

     

    void R3() {

     

     

     

    sign.pop(); sign.pop(); sign.pop();

     

    state.pop(); state.pop(); state.pop();

     

    sign.push('E');st=state.top();

     

    printf("r3 ");

     

    }

     

    void R4() {

     

    sign.pop();

     

    state.pop();

     

    sign.push('E');st=state.top();

     

    printf("r4 ");

     

    }

     

    void R5() {

     

     

     

    sign.pop(); sign.pop(); sign.pop();

     

    state.pop(); state.pop(); state.pop();

     

    sign.push('T');st=state.top();

     

    printf("r5 ");

     

    }

     

    void R6() {

     

     

     

    sign.pop(); sign.pop(); sign.pop();

     

    state.pop(); state.pop(); state.pop();

     

    sign.push('T');st=state.top();

     

    printf("r6 ");

     

    }

     

    void R7() {

     

    sign.pop();

     

    state.pop();

     

    sign.push('T');st=state.top();

     

    printf("r7 ");

     

    }

     

    void R8() {

     

    sign.pop(); sign.pop(); sign.pop();

     

    state.pop(); state.pop(); state.pop();

     

    sign.push('F');st=state.top();

     

    printf("r8 ");

     

    }

     

    void R9() {

     

    sign.pop();

     

    state.pop();

     

    sign.push('F');st=state.top();

     

    printf("r9 ");

     

    }

     

    void R10() {

     

    sign.pop();

     

    state.pop();

     

    sign.push('V');st=state.top();

     

    printf("r10 ");

     

    }

     

    SLR1分析处理函数:

     

    void SLR()

    {

    printf("输入串 状态栈 符号栈 ACTION GOTO   ");

    int i,j,k=1;

    state.push(0); //初始化

    sign.push('#');

    int which;  //对应表项内容

    char c; //输入符号串首

    int a; //坐标

    int b;

    do{

    printf(" ");

    c=m[k-1].temp[0]; //输入符号串首

    cout<<c<<' ';

    for(int j=k;j<=count;j++)

    printf("%s",m[j].temp);

    printf(" ");

    displayStack(state);

     

    displayStack1(sign);

    a=state.top(); //坐标

    b=isVt(c);

    /*if(isOp(c)!=-1)

    temp1=c;

    place.push(temp1);*/

    if(b!=-1)  //输入串首c是终结符

    {

     

    which=ACTION[a][b];

    if(which==-1)

    {

    printf(" acc,分析成功! ");

    flag=1;

    break;

    }

    else if(which==0)

    { printf("error1 ");break; }

    else if(which>=100) //移进

    {

    which=s_r(which);

    printf("s%d ",which);

    sign.push(c);

    state.push(which);

    k++;

    }

    else

    {

    switch(which) //which整型,case不要加''

    {                                                                                                                                                                                                                                                        

    case 1:R1();break;

    case 2:R2();break;

    case 3:R3();break;

    case 4:R4();break;

    case 5:R5();break;

    case 6:R6();break;

    case 7:R7();break;

    case 8:R8();break;

    case 9:R9();break;

    case 10:R10();break;

    default:printf("which=%derror2 ");break;

    }

    //状态转移 Vn

    int e=isVn(sign.top());

    if(e!=-1)

    {

    int convert=GOTO[st][e];

    state.push(convert);

    printf("GOTO[%d,%c]=%d",st,sign.top(),convert);

    }

    }

    }

    else   

    { printf("error_b ");break; }

     

    }while(which!=-1);//while

    }

     5、实验测试

    1.测试用例:i=(i-i*i)#,输入file.txt直接从文件读取输入串,得到结果如下:

     

    四元式结果输出:

     由于图片无法上传便罢

    6、 实验总结 

    本次实验是对理论课上所学知识的应用,重点是理解分析栈和符号栈,这里我采用自行造ACTION和GOTO表,这样SLR分析表就出来了,自动造表还是比较复杂。而且在造表的过程中经常出错,最后在大家的讨论中解决了。造完表后的分析过程并不复杂,按部就班分情况来处理。

    本次实验加深了我对SLR1的分析过程的理解,也加深了对四元式的认识。

     7、源代码

    分为两个CPP

    Siyuanshi.cpp   

    #include "stdafx.h"
    #include<stdlib.h>
    #include<fstream>
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    #define MAX 100
    int mm=0,sum=0;//sum用于计算运算符的个数
                      //mm用于标输入表达式中字符的个数
    char JG='A';
    char str[MAX];//用于存输入表达式
    int  token=0;//左括号的标志
    
    /***********用于更改计算后数组中的值**************/
    void change(int e)
    {
        int f=e+2;
        char ch=str[f];    
        if(ch>='A'&&ch<='Z')
        {
            for(int l=0;l<mm+10;l++)
            {
                if(str[l]==ch)
                    str[l]=JG;
            }
        }
        
        if(str[e]>='A'&&str[e]<='Z')
        {
            for(int i=0;i<mm;i++)
            {
                if(str[i]==str[e])
                    str[i]=JG;
            }
        }    
    }
    
    
    void chengchuchuli(int i,int mm)
    {
        
        i++;
        for( ;i<=mm-1;i++)//处理乘除运算
        {
           if(str[i]=='*'||str[i]=='/') 
           {
               
               cout<<"("<<str[i]<<" "<<str[i-1]<<"  "<<str[i+1]<<"  "<<JG<<")"<<endl;
               change(i-1);
               str[i-1]=str[i]=str[i+1]=JG;
               sum--;
               JG=(char)(int)JG++;
           }
        }
    }
    
    void jiajianchuli(int j,int mm)
    {
        j++;
        for( ;j<=mm-1;j++)//处理加减运算
        {
           if(str[j]=='+'||str[j]=='-') 
           {
               cout<<"("<<str[j]<<" "<<str[j-1]<<"  "<<str[j+1]<<"  "<<JG<<")"<<endl;
               change(j-1);
               str[j-1]=str[j]=str[j+1]=JG;
               sum--;
               JG=(char)(int)JG++;
           }       
        }
    }
    
    /*扫描遍从文件中读入表达式*/
    void scan(FILE *fin)
    {   
            int p[MAX];
            char ch='a';
            int c=-1,q=0;
            while(ch!=EOF)
            {
                ch=getc(fin);
    
                while(ch==' '||ch=='
    '||ch=='	') 
                    ch=getc(fin);//消除空格和换行符
                
                str[mm++]=ch;
                if(ch=='='||ch=='+'||ch=='-'||ch=='*'||ch=='/') 
                    sum++;
                else if(ch=='(') 
                {
                    p[++c]=mm-1;
                }
                else if(ch==')')
                {
                      q=mm-1;
                      chengchuchuli(p[c],q);//从左括号处理到又括号
                      jiajianchuli(p[c],q);                 
                      JG=(char)(int)JG--;
                      str[p[c]]=str[mm-1]=JG;
                      c--;
                      JG=(char)(int)JG++;      
                }
            }
    }    
    
    void siyuanshi()
    {
    
        for(int i=0;i<=mm-1;i++)//处理乘除运算
        {
           if(str[i]=='*'||str[i]=='/') 
           {
               
               cout<<"("<<str[i]<<"  "<<str[i-1]<<"  "<<str[i+1]<<"  "<<JG<<")"<<endl;
               change(i-1);
               str[i-1]=str[i]=str[i+1]=JG;
               sum--;
               JG=(char)(int)JG++;
           }
        
        }
    
        for(int j=0;j<=mm-1;j++)//处理加减运算
        {
           if(str[j]=='+'||str[j]=='-') 
           {
               
               cout<<"("<<str[j]<<"  "<<str[j-1]<<"  "<<str[j+1]<<"  "<<JG<<")"<<endl;
               change(j-1);
               str[j-1]=str[j]=str[j+1]=JG;
               sum--;
               JG=(char)(int)JG++;
           }
        
        } 
        
        for(int k=0;k<=mm-1;k++)//处理赋值运算
        {
           if(str[k]=='=') 
           {
               
               JG=(char)(int)--JG;
               cout<<"("<<str[k]<<"  "<<str[k+1]<<"  "<<"  "<<" "<<str[k-1]<<")"<<endl;
               sum--;
               change(k+1);
               str[k-1]=JG;
           }
        }
    
    }
    
    extern void MAIN(){
        char in[MAX]; //用于接收输入输出文件名
        FILE *fin; 
        cout<<"请输入源文件名(包括后缀名)"<<endl;
        cin>>in;;
        if ((fin=fopen(in,"r"))==NULL) 
        {
          cout<<"error"<<endl;
        }
        cout<<"*********四元式如下*********"<<endl;
        scan(fin);//调用函数从文件中读入表达式     
        siyuanshi();
        if(sum==0) printf("成功?");
        else printf("有错误");
        //关闭文件
        fclose(fin);
        system("pause");
    }

    Bianyi_5.cpp

    // bianyi_5.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <iostream>
    #include <string>
    #include <stack>
    #include <map>
    #include <string>
    #include <cstring>
    #include <iomanip>
    
    using namespace std;
    extern void MAIN();
    #define ADD 1
    #define SUB 2
    #define MUL 3
    #define FH 4
    #define SG 5
    #define ID 6
    #define INT 7
    #define LT 8
    #define LE 9
    #define EQ 10
    #define NE 11
    #define GT 12
    #define GE 13
    #define MHEQ 14
    #define XGMUL 15
    #define ZKH 16
    #define YKH 17
    #define DIV 18 
    #define EQ 19//=
    #define blz 00
    
    #define COUNT 40 
    char* keyword[]={"begin","end","if","then","else","for","do","and","or","not"};//保留字
    
    int count;
    struct eryuanzu
    {
        int a;
        char temp[COUNT];
    }m[COUNT];
    
    void out(int a,char* temp){// 打印二元组
    
        printf("< %d %s >
    ",a,temp);
        m[count].a=a;
        strcpy(m[count].temp,temp);  //
        count++;
    }
    
    stack<int> state;           //状态栈
    stack<char> sign;           //符号栈
    char st; //规约弹出时,状态栈顶元素
    int flag=0; //标志是否是SLR
    stack<string> place;        //变量地址栈
    
                                
    /*                    i  ( ) + - * / =  #
    以1开头的百位数为s移进项,0为error,-1为accept,其余的一位或两位数是r规约项*/
    int ACTION[20][9]={{103,0,0,0,0,0,0,0,0},//0
                        {0,0,0,0,0,0,0,0,-1},
                        {0,0,0,0,0,0,0,104,0},
                        {0,0,0,0,0,0,0,10,0},                                                                                                                                                                                                                      
                        {109,108,0,0,0,0,0,0},
                        {0,0,0,110,111,0,0,0,1},//5 
                        {0,0,4,4,4,112,113,0,4},
                        {0,0,7,7,7,7,7,0,7},
                        {109,108,0,0,0,0,0,0,0},
                        {0,0,9,9,9,9,9,0,9},
                        {109,108,0,0,0,0,0,0,0},//10
                        {109,108,0,0,0,0,0,0,0},
                        {109,108,0,0,0,0,0,0,0},
                        {109,108,0,0,0,0,0,0,0},
                        {0,0,119,110,111,0,0,0,0}, 
                        {0,0,2,2,2,112,113,0,2},//
                        {0,0,3,3,3,112,113,0,3},
                        {0,0,5,5,5,5,5,0,5},
                        {0,0,6,6,6,6,6,0,6},
                        {0,0,8,8,8,8,8,0,8}};//19
    //A V E T F
    int GOTO[20][5]={{1,2,0,0,0},
                    {0,0,0,0,0},//1
                    {0,0,0,0,0},
                    {0,0,0,0,0},
                    {0,0,5,6,7},
                    {0,0,0,0,0},//5
                    {0,0,0,0,0},
                    {0,0,0,0,0},
                    {0,0,14,6,7},
                    {0,0,0,15,7},
                    {0,0,0,16,7},//10
                    {0,0,0,0,17},
                    {0,0,0,0,18},
                    {0,0,0,0,0},
                    {0,0,0,0,0},
                    {0,0,0,0,0},//15
                    {0,0,0,0,0},
                    {0,0,0,0,0},
                    {0,0,0,0,0},
                    {0,0,0,0,0}};//19
    
    void R1();          //A→V=E
    void R2();          //E→E+T
    void R3();          //E→E-T
    void R4();          //E→T
    void R5();          //T→T*F
    void R6();          //T→T/F
    void R7();          //T→F
    void R8();          //F→(E)
    void R9();          //F→i
    void R10();         //V→i
    
    int isOp(char a)  //判断二元运算符及二元运算符的优先级
    {
        int i;
        switch(a)
        {
        case '=':i=0;break;
        case '+':i=1;break;
        case '-':i=1;break;
        case '*':i=2;break;
        case '/':i=2;break;
        default:i=-1;break;
        }
        return i;
    }
    int isVt(char a)
    {
        int i;
        switch(a)
        {
        case 'i':i=0;break;
        case '(':i=1;break;
        case ')':i=2;break;
        case '+':i=3;break;
        case '-':i=4;break;
        case '*':i=5;break;
        case '/':i=6;break;
        case '=':i=7;break;
        case '#':i=8;break;
        default:i=-1;break;
        }
        return i;
    }
    int isVn(char a)
    {
        int i;
        switch(a)
        {
        case 'A':i=0;break;
        case 'V':i=1;break;
        case 'E':i=2;break;
        case 'T':i=3;break;
        case 'F':i=4;break;
        default:i=-1;break;
        }
        return i;
    }
    int s_r(int i)  //移进或者其他
    {
        int result;
        if(i/100==1)    //移进
            result=i-100;
        else
            result=i;  
        return result;
    }
    
    bool invertStack(stack<int> &one_stack) 
    {
        if (one_stack.empty())//if the stack is null,then don't invert it
        {
            return false;
        }
        else
        {
            //init a stack to save the inverted stack
            stack<int> invert;
            while (!one_stack.empty())
            {
                invert.push(one_stack.top());
                one_stack.pop();
            }
            //this moment the stack's inverted state is the stack invert ,so get it back
            one_stack = invert;
            return true;
        }
    }
    
    void displayStack(stack<int> one_stack) //打印输出
    {
        invertStack(one_stack);
        while (!one_stack.empty())
        {
            cout << one_stack.top();
            one_stack.pop();
        }
        cout << '	' << '	' ;
    }
    
    bool invertStack1(stack<char> &one_stack)
    {
        if (one_stack.empty())//if the stack is null,then don't invert it
        {
            return false;
        }
        else
        {
            //init a stack to save the inverted stack
            stack<char> invert;
            while (!one_stack.empty())
            {
                invert.push(one_stack.top());
                one_stack.pop();
            }
            //this moment the stack's inverted state is the stack invert ,so get it back
            one_stack = invert;
            return true;
        }
    }
    
    void displayStack1(stack<char> one_stack)
    {
        invertStack1(one_stack);
        while (!one_stack.empty())
        {
            cout << one_stack.top();
            one_stack.pop();
        }
        cout << '	' << '	';
    }
    
    void SLR()
    {
        printf("输入串		状态栈		符号栈		ACTION		GOTO   ");
        int i,j,k=1;
        state.push(0); //初始化
        sign.push('#'); 
        int which;  //对应表项内容
        char c; //输入符号串首
        int a; //坐标
        int b;
    do{
        printf("
    ");    
        c=m[k-1].temp[0]; //输入符号串首
        cout<<c<<' ';
        for(int j=k;j<=count;j++)
            printf("%s",m[j].temp);
        printf("		");
        displayStack(state);
            
        displayStack1(sign);
        a=state.top(); //坐标
        b=isVt(c);
        /*if(isOp(c)!=-1)
            temp1=c;
        place.push(temp1);*/
        if(b!=-1)  //输入串首c是终结符
        {
            
            which=ACTION[a][b];
            if(which==-1)
            {
                printf(" acc,分析成功!
    ");
                flag=1;
                break;
            }
            else if(which==0)
            {    printf("error项1
     ");break;    }
            else if(which>=100) //移进
            {
                which=s_r(which);
                printf("s%d		",which);
                sign.push(c);
                state.push(which);
                k++;
            }
            else 
            {
                switch(which) //which整型,case不要加''
                {                                                                                                                                                                                                                                                        
                case 1:R1();break;
                case 2:R2();break;
                case 3:R3();break;
                case 4:R4();break;        
                case 5:R5();break;
                case 6:R6();break;
                case 7:R7();break;
                case 8:R8();break;
                case 9:R9();break;
                case 10:R10();break;
                default:printf("which=%derror项2
     ");break;
                }    
                //状态转移 Vn
                int e=isVn(sign.top());
                if(e!=-1)
                {
                int convert=GOTO[st][e];
                state.push(convert);
                printf("GOTO[%d,%c]=%d",st,sign.top(),convert);
                }
            }
        }
        else   
        {    printf("error_b ");break;    }
        
    }while(which!=-1);//while
    }
    
    void R1() {
        
        sign.pop(); sign.pop(); sign.pop();       //弹出符号栈
        state.pop(); state.pop(); state.pop();    //弹出状态栈
        sign.push('A');                         //符号'A'入栈
        st=state.top();
        printf("r1	");
    }
    void R2() {
        
        sign.pop(); sign.pop(); sign.pop();       //弹出符号栈
        state.pop(); state.pop(); state.pop();    //弹出状态栈
        sign.push('E'); st=state.top();                        //符号'E'入栈
        printf("r2		");
    }
    void R3() {
    
        sign.pop(); sign.pop(); sign.pop();
        state.pop(); state.pop(); state.pop();
        sign.push('E');st=state.top();
        printf("r3		");
    }
    void R4() {
        sign.pop();
        state.pop();
        sign.push('E');st=state.top();
        printf("r4		");
    }
    void R5() {
    
        sign.pop(); sign.pop(); sign.pop();
        state.pop(); state.pop(); state.pop();
        sign.push('T');st=state.top();
        printf("r5		");
    }
    void R6() {
    
        sign.pop(); sign.pop(); sign.pop();
        state.pop(); state.pop(); state.pop();
        sign.push('T');st=state.top();
        printf("r6		");
    }
    void R7() {
        sign.pop();
        state.pop();
        sign.push('T');st=state.top();
        printf("r7		");
    }
    void R8() {
        sign.pop(); sign.pop(); sign.pop();
        state.pop(); state.pop(); state.pop();
        sign.push('F');st=state.top();
        printf("r8		");
    }
    void R9() {
        sign.pop();
        state.pop();
        sign.push('F');st=state.top();
        printf("r9		");
    }
    void R10() {
        sign.pop();
        state.pop();
        sign.push('V');st=state.top();
        printf("r10		");
    }
    
    ///////////////////////////////////////////////
    void scanner(FILE *p)
    {    
        char filein[40],fileout[40]; //文件名
        printf("请输入要打开的源文件名(包括路径)
    ");
        scanf("%s",filein);
        //printf("请输入要输出的目标文件名(包括路径)
    ");
        //scanf("%s",fileout);
        if((p=fopen(filein,"r"))==NULL) {printf("输入文件打开有错!
    ");return;}
    //    if((q=fopen("fileout","rw"))==NULL) {printf("输出文件打开有错!
    ");return;}
    
        char token[COUNT]; //输出数组
        int r=0,i=0;
        char ch;    
        ch=fgetc(p);
        while(!feof(p)) //没有读到文件末尾
    {
        if(isdigit(ch))
        {
            i=0;
            token[i]=ch;
            while(isdigit(ch=fgetc(p)))
            {
                i++;
                token[i]=ch;
            }
            token[i+1]=''; //整数结束。不要忘结束标志!
            fseek(p,-1,1); //重定向到当前位置的前一个!
            out(INT,token);
            //fprintf(q,"%d %s
    ",INT,token);
        }
        else if(isalpha(ch))
        {
            i=0;
            int flag=0; //标志是否是保留字,默认不是
            token[i]=tolower(ch);
            while(isalpha(ch=fgetc(p)))
            {
                i++;
                token[i]=tolower(ch);
            }
            token[i+1]=''; 
            fseek(p,-1,1);
            for(r=0;r<8;r++)
            {
                if(!strcmp(token,keyword[r]))
                {
                    printf("<blz %s>
    ",token);
                //    fprintf(q,"%d %s
    ","保留字",token);
                    flag=1;
                    break;
                }
            }    
            if(!flag)
            {    out(ID,token);    
            //    fprintf(q,"%d %s
    ",ID,token);
            }
        }
        else
        {
            i=0;
            switch(ch)
            {
            case '+':{    token[i]=ch;
                        token[i+1]=''; 
                        out(ADD,token);    
                        }break;
            case '-':{    token[i]=ch;
                        token[i+1]=''; 
                        out(SUB,token);}break;
            case '*':{    token[i]=ch;
                        token[i+1]=''; 
                        out(MUL,token);}break;
            case ';':{    token[i]=ch;
                        token[i+1]=''; 
                        out(FH,token);}break;
            case '|':{    token[i]=ch;
                        token[i+1]=''; 
                        out(SG,token);}break;
            case '(':{    token[i]=ch;
                        token[i+1]=''; 
                        out(ZKH,token);}break;
            case ')':{    token[i]=ch;
                        token[i+1]=''; 
                        out(YKH,token);}break;
            case '=':{    token[i]=ch;
                        token[i+1]=''; 
                        out(EQ,token);}break;
            case ' ':{    break;} //空格直接跳
            case '#':{    break;} //井号用作结尾            
            case '<':{token[i]=ch;
                    ch=fgetc(p);
                    if(ch=='='){
                        token[i+1]='=';
                        token[i+2]=''; 
                        out(LE,token);
                    }
                    else if(ch=='>'){
                        token[i+1]='>';
                        token[i+2]='';
                        out(NE,token);
                    }
                    else 
                    {    printf(" error 
    ");
                        fseek(p,-1,1);    //多读的要回退一个字符
                    }
                     }break;
                    
            case '>':{token[i]=ch;
                    ch=fgetc(p);
                    if(ch=='=')
                    {
                        token[i+1]='=';
                        token[i+2]='';
                        out(GE,token);
                    }
                    else 
                    {    printf(" error 
    ");
                        fseek(p,-1,1);    //多读的要回退一个字符
                    }
                    }break;
            case ':':{token[i]=ch;
                    ch=fgetc(p);
                    if(ch=='='){
                        token[i+1]='=';
                        token[i+2]='';
                        out(MHEQ,token);
                    }
                    else 
                    {    printf(" error 
    ");
                        fseek(p,-1,1);    //多读的要回退一个字符
                    }
                     }break;
        case '/':{token[i]=ch;
                    ch=fgetc(p);
                    if(ch=='*')
                    {    
                        token[i+1]='*';
                        token[i+2]='';
                        out(XGMUL,token);
                        while(1)    //注释部分的处理!
                        {
                            ch=fgetc(p);
                            if(ch=='*')
                            {
                                if((ch=fgetc(p))=='/')
                                    break;
                            }
                        }
                    }
                    else // 除号,修改第一次程序部分
                    {    /*printf(" error 
    ");
                        fseek(p,-1,1);    */
                        out(DIV,token);
                        fseek(p,-1,1);//多读的要回退一个字符
                    }
                    }break;
            default:{
                        printf(" error
     ");
                    }break;
                        
            }
        }
        ch=fgetc(p);
    }
        fclose(p);
    }
    int main(int argc, char* argv[])
    {
        printf("编译原理实验_5:SLR分析程序(待分析内容在文件file.txt中,以#结尾)
    ");
        FILE *fin,*q;
        scanner(fin);
        strcpy(m[count].temp,"#");//! 
        count=count+1;
        //scanner(p,q);
        SLR();
        MAIN();
        return 0;
    }

    ---内容结束---

  • 相关阅读:
    OpenCV之图像归一化(normalize)
    虚拟机网络模式说明
    大端模式和小端模式
    ASCII、Unicode、UTF-8、UTF-8(without BOM)、UTF-16、UTF-32傻傻分不清
    MFC窗口通过OpenCV显示图片
    基于FFmpeg的Dxva2硬解码及Direct3D显示(五)
    PyQt5播放实时视频流或本地视频文件
    PyQt5信号与槽关联的两种方式
    PyCharm离线安装PyQt5_tools(QtDesigner)
    DC: 8
  • 原文地址:https://www.cnblogs.com/yh-blog/p/9181603.html
Copyright © 2020-2023  润新知