精华内容
下载资源
问答
  • SLR1文法分析程序(C++)

    2018-06-10 14:52:56
    文法为: 0:S->E 1:E->E+E 2:E->E*E 3:E->(E) 4:E->id 运行时只需输入待验证的句子即可 如要实现其他SLR1文法的识别,只需修改头文件和错误处理函数即可 作者:WMD 日期:2018-6-1
  • LL1,LR,SLR文法的判别

    千次阅读 多人点赞 2020-12-02 09:05:29
    临近期末考试,总结了几种文法的判别方法,供大家参考学习。
        临近期末考试,总结了几种文法的判别方法,供大家参考学习。
    

    文法的判别方法总结

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • 完整的编译原理slr(1)文法的判定及其分析器的构造课程设计报告,附录代码有点长,可适当删除,保留核心代码
  • 编译原理实验之SLR1文法分析

    千次阅读 2018-06-14 09:47:00
    ---内容开始--- 这是一份编译原理实验报告,分析表是手动造的,可以作为借鉴。 基于 SLR(1) 分析法的语法制导翻译及中间...2 、目标任务[ 实验 项目] 完成以下描述赋值语句 SLR(1)文法语法制导生成中间代码四元式...

    ---内容开始---

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

    基于  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 >\n",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\t");

     

    }

     

    void R2() {

     

     

     

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

     

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

     

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

     

    printf("r2\t\t");

     

    }

     

    void R3() {

     

     

     

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

     

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

     

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

     

    printf("r3\t\t");

     

    }

     

    void R4() {

     

    sign.pop();

     

    state.pop();

     

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

     

    printf("r4\t\t");

     

    }

     

    void R5() {

     

     

     

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

     

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

     

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

     

    printf("r5\t\t");

     

    }

     

    void R6() {

     

     

     

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

     

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

     

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

     

    printf("r6\t\t");

     

    }

     

    void R7() {

     

    sign.pop();

     

    state.pop();

     

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

     

    printf("r7\t\t");

     

    }

     

    void R8() {

     

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

     

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

     

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

     

    printf("r8\t\t");

     

    }

     

    void R9() {

     

    sign.pop();

     

    state.pop();

     

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

     

    printf("r9\t\t");

     

    }

     

    void R10() {

     

    sign.pop();

     

    state.pop();

     

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

     

    printf("r10\t\t");

     

    }

     

    SLR1分析处理函数:

     

    void SLR()

    {

    printf("输入串\t\t状态栈\t\t符号栈\t\tACTION\t\tGOTO   ");

    int i,j,k=1;

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

    sign.push('#');

    int which;  //对应表项内容

    char c; //输入符号串首

    int a; //坐标

    int b;

    do{

    printf("\n");

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

    cout<<c<<' ';

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

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

    printf("\t\t");

    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,分析成功!\n");

    flag=1;

    break;

    }

    else if(which==0)

    { printf("error1\n ");break; }

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

    {

    which=s_r(which);

    printf("s%d\t\t",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\n ");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=='\n'||ch=='\t') 
                    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 >\n",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 << '\t' << '\t' ;
    }
    
    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 << '\t' << '\t';
    }
    
    void SLR()
    {
        printf("输入串\t\t状态栈\t\t符号栈\t\tACTION\t\tGOTO   ");
        int i,j,k=1;
        state.push(0); //初始化
        sign.push('#'); 
        int which;  //对应表项内容
        char c; //输入符号串首
        int a; //坐标
        int b;
    do{
        printf("\n");    
        c=m[k-1].temp[0]; //输入符号串首
        cout<<c<<' ';
        for(int j=k;j<=count;j++)
            printf("%s",m[j].temp);
        printf("\t\t");
        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,分析成功!\n");
                flag=1;
                break;
            }
            else if(which==0)
            {    printf("error项1\n ");break;    }
            else if(which>=100) //移进
            {
                which=s_r(which);
                printf("s%d\t\t",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\n ");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\t");
    }
    void R2() {
        
        sign.pop(); sign.pop(); sign.pop();       //弹出符号栈
        state.pop(); state.pop(); state.pop();    //弹出状态栈
        sign.push('E'); st=state.top();                        //符号'E'入栈
        printf("r2\t\t");
    }
    void R3() {
    
        sign.pop(); sign.pop(); sign.pop();
        state.pop(); state.pop(); state.pop();
        sign.push('E');st=state.top();
        printf("r3\t\t");
    }
    void R4() {
        sign.pop();
        state.pop();
        sign.push('E');st=state.top();
        printf("r4\t\t");
    }
    void R5() {
    
        sign.pop(); sign.pop(); sign.pop();
        state.pop(); state.pop(); state.pop();
        sign.push('T');st=state.top();
        printf("r5\t\t");
    }
    void R6() {
    
        sign.pop(); sign.pop(); sign.pop();
        state.pop(); state.pop(); state.pop();
        sign.push('T');st=state.top();
        printf("r6\t\t");
    }
    void R7() {
        sign.pop();
        state.pop();
        sign.push('T');st=state.top();
        printf("r7\t\t");
    }
    void R8() {
        sign.pop(); sign.pop(); sign.pop();
        state.pop(); state.pop(); state.pop();
        sign.push('F');st=state.top();
        printf("r8\t\t");
    }
    void R9() {
        sign.pop();
        state.pop();
        sign.push('F');st=state.top();
        printf("r9\t\t");
    }
    void R10() {
        sign.pop();
        state.pop();
        sign.push('V');st=state.top();
        printf("r10\t\t");
    }
    
    ///
    void scanner(FILE *p)
    {    
        char filein[40],fileout[40]; //文件名
        printf("请输入要打开的源文件名(包括路径)\n");
        scanf("%s",filein);
        //printf("请输入要输出的目标文件名(包括路径)\n");
        //scanf("%s",fileout);
        if((p=fopen(filein,"r"))==NULL) {printf("输入文件打开有错!\n");return;}
    //    if((q=fopen("fileout","rw"))==NULL) {printf("输出文件打开有错!\n");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]='\0'; //整数结束。不要忘结束标志!
            fseek(p,-1,1); //重定向到当前位置的前一个!
            out(INT,token);
            //fprintf(q,"%d %s\n",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]='\0'; 
            fseek(p,-1,1);
            for(r=0;r<8;r++)
            {
                if(!strcmp(token,keyword[r]))
                {
                    printf("<blz %s>\n",token);
                //    fprintf(q,"%d %s\n","保留字",token);
                    flag=1;
                    break;
                }
            }    
            if(!flag)
            {    out(ID,token);    
            //    fprintf(q,"%d %s\n",ID,token);
            }
        }
        else
        {
            i=0;
            switch(ch)
            {
            case '+':{    token[i]=ch;
                        token[i+1]='\0'; 
                        out(ADD,token);    
                        }break;
            case '-':{    token[i]=ch;
                        token[i+1]='\0'; 
                        out(SUB,token);}break;
            case '*':{    token[i]=ch;
                        token[i+1]='\0'; 
                        out(MUL,token);}break;
            case ';':{    token[i]=ch;
                        token[i+1]='\0'; 
                        out(FH,token);}break;
            case '|':{    token[i]=ch;
                        token[i+1]='\0'; 
                        out(SG,token);}break;
            case '(':{    token[i]=ch;
                        token[i+1]='\0'; 
                        out(ZKH,token);}break;
            case ')':{    token[i]=ch;
                        token[i+1]='\0'; 
                        out(YKH,token);}break;
            case '=':{    token[i]=ch;
                        token[i+1]='\0'; 
                        out(EQ,token);}break;
            case ' ':{    break;} //空格直接跳
            case '#':{    break;} //井号用作结尾            
            case '<':{token[i]=ch;
                    ch=fgetc(p);
                    if(ch=='='){
                        token[i+1]='=';
                        token[i+2]='\0'; 
                        out(LE,token);
                    }
                    else if(ch=='>'){
                        token[i+1]='>';
                        token[i+2]='\0';
                        out(NE,token);
                    }
                    else 
                    {    printf(" error \n");
                        fseek(p,-1,1);    //多读的要回退一个字符
                    }
                     }break;
                    
            case '>':{token[i]=ch;
                    ch=fgetc(p);
                    if(ch=='=')
                    {
                        token[i+1]='=';
                        token[i+2]='\0';
                        out(GE,token);
                    }
                    else 
                    {    printf(" error \n");
                        fseek(p,-1,1);    //多读的要回退一个字符
                    }
                    }break;
            case ':':{token[i]=ch;
                    ch=fgetc(p);
                    if(ch=='='){
                        token[i+1]='=';
                        token[i+2]='\0';
                        out(MHEQ,token);
                    }
                    else 
                    {    printf(" error \n");
                        fseek(p,-1,1);    //多读的要回退一个字符
                    }
                     }break;
        case '/':{token[i]=ch;
                    ch=fgetc(p);
                    if(ch=='*')
                    {    
                        token[i+1]='*';
                        token[i+2]='\0';
                        out(XGMUL,token);
                        while(1)    //注释部分的处理!
                        {
                            ch=fgetc(p);
                            if(ch=='*')
                            {
                                if((ch=fgetc(p))=='/')
                                    break;
                            }
                        }
                    }
                    else // 除号,修改第一次程序部分
                    {    /*printf(" error \n");
                        fseek(p,-1,1);    */
                        out(DIV,token);
                        fseek(p,-1,1);//多读的要回退一个字符
                    }
                    }break;
            default:{
                        printf(" error\n ");
                    }break;
                        
            }
        }
        ch=fgetc(p);
    }
        fclose(p);
    }
    int main(int argc, char* argv[])
    {
        printf("编译原理实验_5:SLR分析程序(待分析内容在文件file.txt中,以#结尾)\n");
        FILE *fin,*q;
        scanner(fin);
        strcpy(m[count].temp,"#");//! 
        count=count+1;
        //scanner(p,q);
        SLR();
        MAIN();
        return 0;
    }

     

     

    ---内容结束---

    转载于:https://www.cnblogs.com/yh-blog/p/9181603.html

    展开全文
  • 编译原理的课程设计SLR(1)分析器 包含求FIRST,FOLLOW集合 LR(0)项目规范集组 SLR(1)分析表 SLR(1)分析器
  • 编译原理SLR1分析方法

    2009-12-07 16:50:55
    利用SLR1分析方法进行语法分析,分析表达式文法文法G E->T|E+T T->F|T*F F->i|(E)
  • JAVA实现SLR(1)文法的分析器

    千次阅读 2020-01-12 15:32:28
    (3)判断该文法是否为SLR文法 (4)输入字符串,按照SLR分析法判断该字符串的语法是否正确,并给出判断过程 代码的思路: 将文法中的每一个句子的左部和右部进行分离。其中,右部的每一个终结符和非终结符也是...

    代码功能:

    (1)计算非终结符的FIRST和FOLLOW集

    (2)构造SLR分析表

    (3)判断该文法是否为SLR文法

    (4)输入字符串,按照SLR分析法判断该字符串的语法是否正确,并给出判断过程

    代码的思路:

    1. 将文法中的每一个句子的左部和右部进行分离。其中,右部的每一个终结符和非终结符也是单独保存的。
    2. 将左部和右部分离后的文法中的终结符和非终结符识别出来。一般左部都是非终结符,那么右部除去非终结符就是终结符了。
    3. 计算FIRST集。设置一个变量_ALTERED_,在每次有新的终结符添加到FIRST集中的时候,就将_ALTERED_置位true。计算FIRST集的方法如下:如果产生式右部是终结符a,且这个终结符a不在FIRST集中,则添加。如果是非终结符A,则将A的FIRST集中的所有自己没有的终结符添加到自己的FIRST集中。如果A的终结符中包含ε,则继续判断下一个。
    4. 计算FOLLOW集。设置一个变量_ALTERED_,在每次有新的终结符添加到FOLLOW集中的时候,就将_ALTERED_置位true。计算FOLLOW集的方法如下:1、遍历文法中的所有产生式,所有出现在非终结符右边的终结符加入到相应follow集中,如果非终结符右边没有东西,则把$加入。 2、遍历文法中的所有产生式,若产生式最右边是非终结符,把左部非终结符的follow集的所有元素都添加到对应非终结符中。3、将$加入到第一个非终结符的follow集中。
    5. 根据每一条产生式,生成项目集规范族程序设计的是对项目集规范族中的每一个项目集中的每一条项目都进行分析,产生了新的项目集就添加到项目集规范族中。
    6. 根据项目集规范族和FOLLOW集生成SLR分析表。根据·的位置判断是否将其添加到SLR分析表中,很容易。如果·后面的是终结符,将转移动作s添加到SLR分析表中的ACTION部分;如果·后面的是终结符,将转移添加到SLR分析表的GOTO部分;如果·在项目的末尾,将归约动作r添加到SLR分析表的ACTION部分。
    7. 设计词法分析器,用于分析输入的程序。
    8. 根据SLR分析表和词法分析的结果进行词法分析。

    程序代码:

    CSDN下载了直接用Eclipse打开:https://download.csdn.net/download/oLOVED/12098174

    GitHub上的项目:https://github.com/z1178902213/SLRAnalyser-

    程序运行:

    文法:

    E->E+T
    E->E-T
    E->T
    T->T*K
    T->T/K
    T->K
    K->K%F
    K->K^F
    K->F
    F->(E) 
    F->id
    F->num

    测试程序:

    a+xyz*10+(c/d)+(xyz%a)+(d^5)

    运行结果:

    终结符:[+, -, *, /, %, ^, (, ), id, num]
    非终结符:[E, T, K, F]
    文法如下所示:
    (1)E->E+T
    (2)E->E-T
    (3)E->T
    (4)T->T*K
    (5)T->T/K
    (6)T->K
    (7)K->K%F
    (8)K->K^F
    (9)K->F
    (10)F->(E)
    (11)F->id
    (12)F->num

    文法的First集为:
    First(E) = { ( id num }
    First(T) = { ( id num }
    First(K) = { ( id num }
    First(F) = { ( id num }

    文法的Follow集为:
    Follow(E) = { + - ) $ }
    Follow(T) = { $ * / + - ) }
    Follow(K) = { $ % ^ * / + - ) }
    Follow(F) = { $ % ^ * / + - ) }

    该文法的项目集规范族如下所示:
    I0:
    START->·E
    E->·E+T
    E->·E-T
    E->·T
    T->·T*K
    T->·T/K
    T->·K
    K->·K%F
    K->·K^F
    K->·F
    F->·(E)
    F->·id
    F->·num

    I1:
    START->E·
    E->E·+T
    E->E·-T

    I2:
    E->T·
    T->T·*K
    T->T·/K

    I3:
    T->K·
    K->K·%F
    K->K·^F

    I4:
    K->F·

    I5:
    F->(·E)
    E->·E+T
    E->·E-T
    E->·T
    T->·T*K
    T->·T/K
    T->·K
    K->·K%F
    K->·K^F
    K->·F
    F->·(E)
    F->·id
    F->·num

    I6:
    F->id·

    I7:
    F->num·

    I8:
    E->E+·T
    T->·T*K
    T->·T/K
    T->·K
    K->·K%F
    K->·K^F
    K->·F
    F->·(E)
    F->·id
    F->·num

    I9:
    E->E-·T
    T->·T*K
    T->·T/K
    T->·K
    K->·K%F
    K->·K^F
    K->·F
    F->·(E)
    F->·id
    F->·num

    I10:
    T->T*·K
    K->·K%F
    K->·K^F
    K->·F
    F->·(E)
    F->·id
    F->·num

    I11:
    T->T/·K
    K->·K%F
    K->·K^F
    K->·F
    F->·(E)
    F->·id
    F->·num

    I12:
    K->K%·F
    F->·(E)
    F->·id
    F->·num

    I13:
    K->K^·F
    F->·(E)
    F->·id
    F->·num

    I14:
    F->(E·)
    E->E·+T
    E->E·-T

    I15:
    E->E+T·
    T->T·*K
    T->T·/K

    I16:
    E->E-T·
    T->T·*K
    T->T·/K

    I17:
    T->T*K·
    K->K·%F
    K->K·^F

    I18:
    T->T/K·
    K->K·%F
    K->K·^F

    I19:
    K->K%F·

    I20:
    K->K^F·

    I21:
    F->(E)·

    SLR分析表:

    栈                                输入        动作
    0                                         a+xyz*10+(c/d)+(xyz%a)+(d^5)$        移进
    0id6                                      +xyz*10+(c/d)+(xyz%a)+(d^5)$        按F->[id]归约
    0F4                                       +xyz*10+(c/d)+(xyz%a)+(d^5)$        按K->[F]归约
    0K3                                       +xyz*10+(c/d)+(xyz%a)+(d^5)$        按T->[K]归约
    0T2                                       +xyz*10+(c/d)+(xyz%a)+(d^5)$        按E->[T]归约
    0E1                                       +xyz*10+(c/d)+(xyz%a)+(d^5)$        移进
    0E1+8                                     xyz*10+(c/d)+(xyz%a)+(d^5)$        移进
    0E1+8id6                                   *10+(c/d)+(xyz%a)+(d^5)$        按F->[id]归约
    0E1+8F4                                    *10+(c/d)+(xyz%a)+(d^5)$        按K->[F]归约
    0E1+8K3                                    *10+(c/d)+(xyz%a)+(d^5)$        按T->[K]归约
    0E1+8T15                                   *10+(c/d)+(xyz%a)+(d^5)$        移进
    0E1+8T15*10                                 10+(c/d)+(xyz%a)+(d^5)$        移进
    0E1+8T15*10num7                               +(c/d)+(xyz%a)+(d^5)$        按F->[num]归约
    0E1+8T15*10F4                                 +(c/d)+(xyz%a)+(d^5)$        按K->[F]归约
    0E1+8T15*10K17                                +(c/d)+(xyz%a)+(d^5)$        按T->[T, *, K]归约
    0E1+8T15                                      +(c/d)+(xyz%a)+(d^5)$        按E->[E, +, T]归约
    0E1                                           +(c/d)+(xyz%a)+(d^5)$        移进
    0E1+8                                          (c/d)+(xyz%a)+(d^5)$        移进
    0E1+8(5                                         c/d)+(xyz%a)+(d^5)$        移进
    0E1+8(5id6                                       /d)+(xyz%a)+(d^5)$        按F->[id]归约
    0E1+8(5F4                                        /d)+(xyz%a)+(d^5)$        按K->[F]归约
    0E1+8(5K3                                        /d)+(xyz%a)+(d^5)$        按T->[K]归约
    0E1+8(5T2                                        /d)+(xyz%a)+(d^5)$        移进
    0E1+8(5T2/11                                      d)+(xyz%a)+(d^5)$        移进
    0E1+8(5T2/11id6                                    )+(xyz%a)+(d^5)$        按F->[id]归约
    0E1+8(5T2/11F4                                     )+(xyz%a)+(d^5)$        按K->[F]归约
    0E1+8(5T2/11K18                                    )+(xyz%a)+(d^5)$        按T->[T, /, K]归约
    0E1+8(5T2                                          )+(xyz%a)+(d^5)$        按E->[T]归约
    0E1+8(5E14                                         )+(xyz%a)+(d^5)$        移进
    0E1+8(5E14)21                                       +(xyz%a)+(d^5)$        按F->[(, E, )]归约
    0E1+8F4                                             +(xyz%a)+(d^5)$        按K->[F]归约
    0E1+8K3                                             +(xyz%a)+(d^5)$        按T->[K]归约
    0E1+8T15                                            +(xyz%a)+(d^5)$        按E->[E, +, T]归约
    0E1                                                 +(xyz%a)+(d^5)$        移进
    0E1+8                                                (xyz%a)+(d^5)$        移进
    0E1+8(5                                               xyz%a)+(d^5)$        移进
    0E1+8(5id6                                               %a)+(d^5)$        按F->[id]归约
    0E1+8(5F4                                                %a)+(d^5)$        按K->[F]归约
    0E1+8(5K3                                                %a)+(d^5)$        移进
    0E1+8(5K3%12                                              a)+(d^5)$        移进
    0E1+8(5K3%12id6                                            )+(d^5)$        按F->[id]归约
    0E1+8(5K3%12F19                                            )+(d^5)$        按K->[K, %, F]归约
    0E1+8(5K3                                                  )+(d^5)$        按T->[K]归约
    0E1+8(5T2                                                  )+(d^5)$        按E->[T]归约
    0E1+8(5E14                                                 )+(d^5)$        移进
    0E1+8(5E14)21                                               +(d^5)$        按F->[(, E, )]归约
    0E1+8F4                                                     +(d^5)$        按K->[F]归约
    0E1+8K3                                                     +(d^5)$        按T->[K]归约
    0E1+8T15                                                    +(d^5)$        按E->[E, +, T]归约
    0E1                                                         +(d^5)$        移进
    0E1+8                                                        (d^5)$        移进
    0E1+8(5                                                       d^5)$        移进
    0E1+8(5id6                                                     ^5)$        按F->[id]归约
    0E1+8(5F4                                                      ^5)$        按K->[F]归约
    0E1+8(5K3                                                      ^5)$        移进
    0E1+8(5K3^13                                                    5)$        移进
    0E1+8(5K3^13num7                                                 )$        按F->[num]归约
    0E1+8(5K3^13F20                                                  )$        按K->[K, ^, F]归约
    0E1+8(5K3                                                        )$        按T->[K]归约
    0E1+8(5T2                                                        )$        按E->[T]归约
    0E1+8(5E14                                                       )$        移进
    0E1+8(5E14)21                                                     $        按F->[(, E, )]归约
    0E1+8F4                                                           $        按K->[F]归约
    0E1+8K3                                                           $        按T->[K]归约
    0E1+8T15                                                          $        按E->[E, +, T]归约
    0E1                                                               $        接受
    程序正确
     

     

    展开全文
  • 该程序能够根据给定的文法判断它是否为LR0,SLR1,LR1,LALR1文法; 打印项目集,分析表,Go函数; 若文法属于LR1,将进行LALR1文法判断,若属于LALR1文法,将继续打印LALR1文法的项目集,分析表和Go函数。
  • 因为SLR文法分析法就是对LR(0)的一种优化,它提供了一种解决冲突的方法,所以很多之前在LR(0)提及的东西,在此只提供一个引用。 LR(0)文法分析法 算法描述 SLR文法构造分析表的主要思想是:许多冲突性的动作都可能...

    前情提要

    因为SLR文法分析法就是对LR(0)的一种优化,它提供了一种解决冲突的方法,所以很多之前在LR(0)提及的东西,在此只提供一个引用。
    LR(0)文法分析法

    算法描述

    SLR文法构造分析表的主要思想是:许多冲突性的动作都可能通过考察有关非终结符的FOLLOW集而获解决。
    解决冲突的方法:解决冲突的方法是分析所有含A和B的句型,考察集合FOLLOW(A)和FOLLOW(B),如果这两个集合不相交,而且也不包含b,那么当状态I面临输入符号a时,我们可以使用如下策略:

    • 若a=b,则移进。
    • 若a∈FOLLOW(A),则用产生式A→α进行归约;
    • 若a∈FOLLOW(B),则用产生式B→α进行归约;
    • 此外,报错*

    SLR的基本算法:

    • 假定LR(0)规范族的一个项目集I中含有m个移进项目
      A1→α•a1β1,A2→α•a2β2,…,Am→α•amβm;
      同时含有n个归约项目
      B1→α•,B2→α•,…,B3→α•,
    • 如果集合{ a1,…, am},FOLLOW(B1),…,FOLLOW(Bn)两两不相交(包括不得有两个FOLLOW集合有#),则隐含在I中的动作冲突可以通过检查现行输入符号a属于上述n+1个集合中的哪个集合而活的解决:
      • 若a是某个ai,i=1,2,…,m,则移进。
      • 若a∈FOLLOW(Bi),i=1,2,…,m,则用产生式Bi→α进行归约;
      • 此外,报错

    这种冲突的解决方法叫做SLR(1)解决办法

    SLR语法分析表的构造方法:
    首先把G拓广为G’,对G’构造LR(0)项目集规范族C和活前缀识别自动机的状态转换函数GO。函数ACTION和GOTO可按如下方法构造:

    • 若项目A→α•bβ属于Ik,GO(Ik,a)= Ij,a为终结符,置ACTION[k,a]为“把状态j和符号a移进栈”,简记为“sj”;
    • 若项目A→α•属于Ik,那么,对任何非终结符a,a∈FOLLOW(A),置ACTION[k,a]为“用产生式A→α进行归约”,简记为“rj”;其中,假定A→α为文法G’的第j个产生式
    • 若项目S’→S•属于Ik,则置ACTION[k,#]为可“接受”,简记为“acc”;
    • 若GO(Ik, A)= Ij,A为非终结符,则置GOTO[k, A]=j;

    分析表中凡不能用规则1至4填入信息的空白格均填上“出错标志”。
    语法分析器的初始状态是包含S’ →•S的项目集合的状态
    SLR解决的冲突只是移进-规约冲突规约-规约冲突

    Input

    7
    S->E
    E->E+T
    E->T
    T->T*F
    T->F
    F->(E)
    F->i

    Output

    生成的项目表

    这里写图片描述

    非终结符的follow集合

    这里写图片描述

    项目规范族

    这里写图片描述
    这里写图片描述

    构造出的DFA

    这里写图片描述

    SLR文法表和一个例子的文法分析过程

    这里写图片描述


    展开全文
  • 文章目录自顶向下分析自底向上分析文法转换LL(1)文法S 文法ε产生式的使用非终结符的后继符号集产生式的可选集Q文法串首终结符集LL(1)文法SELECT集、FOLLOW集、FIRST集计算 自顶向下分析 自顶向下分析指的是最左...
  • LALR(1)类文法判定及其分析器构造 课程设计 内容全面,LALR(1)类文法判定及其分析器构造
  • //非终结符编号,0号为扩展文法开始符 int idPro = 1; //产生式编号,0号为扩展文法开始符 int JING; //# 号 int EMPTY = 5*SIZE; //空串 int startVt = -1; //判断是否处理了开始符,只处理一次 int ERROR = 4*...
  • 【编译原理】SLR(1)分析方法(c++实现)

    千次阅读 热门讨论 2020-05-21 21:15:30
    Created with Raphaël 2.2.0输入文法拓广文法构造DFA(识别活前缀的自动机)SLR(1)分析表SLR(1)分析输入串 当然也要求非终极符号的FIRST和FOLLOW集,这个步骤在构建分析表之前做就好,没什么固定顺序   代码 ...
  • SLR(1)分析法的实现

    2018-07-23 13:25:15
    1、算符优先分析法(需要先来判断文法是否为算符优先文法) 2、LR(0)分析法 3、SLR1)分析法 该程序的功能为,给定输入,程序按照先后顺序将使用的产生式输出。 如,输入25.6 * 14.5 + 2(首先经过词法分析,将...
  • 用C语言编写实现编译原理实验判断文法是不是LL1文法的程序。程序简单易懂,且基本功能都实现了。
  • 一、SLR文法的分析 ①先求出该文法的FOLLOW集 **② ** 二、SLR文法分析表的构造
  • SLR(1)文法分析器 基于Python3的SLR(1)文法分析器。目前的功能: 分析文法各非终结符号的FOLLOW(A)集合 分析文法所有的有效项目集族 计算文法SLR(1)分析矩阵 简单的输入串分割(词法分析)功能 判断输入串是否为...
  • SLR1)语法分析器

    2020-11-13 23:05:51
    SLR1)语法分析器
  • 首先来看张图,上图是四种文法的包含关系,即 LR(1)文法范围最大,而 LR(0)文法范围最小。同时也说明了四种文法分析过程的强弱,即 LR(1)文法分析最强,而 LR(0)文法分析最弱。 那为什么没有 LL(1)文法呢?因为它...
  • 证明下列文法是LL(1)文法但不是SLR(1)文法 S->AaAb|BbBa A->εB->ε  (1)首先该文法无左递归存在,没有公共左因子.  其次:对于S→AaAb|BbBa FIRST(AaAb)={a} FIRST(BbBa)={b}  FIRST(AaAb)∩FIRST(BbBa)=...
  • SLR(1)分析法

    万次阅读 多人点赞 2019-05-26 09:52:11
    文章目录SLR分析法的基本思想SLR(1)分析表的构造 LR(0)文法要求文法的每一个LR(0)项目都不含有冲突的项目,这个条件比较苛刻。对于大多数程序设计语言来说,一般都不能满足LR(0)文法的条件。 例如: 不难看出在状态...
  • LL(1),LR(0),SLR(1)文法分析器 软件介绍 该软件是一款集成的文法分析器,用户输入文法后能识别LL(1)文法,LR(0)文法SLR(1)文法,并为用户提供分析表。 开发环境:Windows 10 开发工具:QT 5.9 界面介绍 ...
  • 完成以下描述赋值语句 SLR(1)文法语法制导生成中间代码四元式的过程。G[E]: S→V=E E →E+T∣E-T∣T T→T*F∣T/F∣F F→(E)∣i V=I 2.[设计说明] 终结符号i 为用户定义的简单变量,即标识符的定义。 3.[设计要求] (1...
  • SLR1

    千次阅读 2020-05-11 09:45:37
    SLR文法不存在归约-归约冲突,有可能存在移进-归约冲突,但是如果可以用 follow集解决则是 SLR文法。 换句话说,SLR文法分析过程可以解决归约-归约冲突,但是不一定能解决移进-归约冲突。 用 follow集来处理即出现移...
  • LL(1)文法是根据SELECT集进行判别,如果相同左部产生式的SELECT交集都为空,则是LL(1)文法,否则不是LL(1)文法。 FIRST集判断 如A->aB | CD ①以终结符开头,把这个终结符a放到A的FIRST里 ②以非终结符开头,...
  • 怎么判断一个文法是LR(0)

    千次阅读 2020-12-23 12:39:44
    展开全部LR(0)分析就是LR(K)分析当K=0的情况,32313133353236313431303231363533e78988e69d8331333431366431亦即在分析的每一步,只要根据当前的栈顶状态 (或者说根据当前分析栈中已移进或归约出的全部文法符号)就能...
  • 判断SLR(1)文法:****3.判断LR(1)文法:****4.判断LALR(1)文法:** 关系:LR(0)<SLR(1)<LALR(1)<LR(1) 如果前边一个文法判断是后边都是 比如:是LR(0)也是 SLR(1)也是 LALR(1)也是LR(1) 不是LR(0...
  • select集的求解方法、判断LL(1)文法的方法 求解方法: 注意:有两种情况,如果非终结符能推出空集的话就要与非终结符的FOLLOW集再并一下。 用SELECT集判断LL(1)文法的方法: 用SELECT集判断是否为LL(1)文法的例题...
  • 完成以下描述赋值语句 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 2 3 4 5 ... 20
收藏数 425
精华内容 170
关键字:

判断slr1文法