zoukankan      html  css  js  c++  java
  • SLR(1)语法分析

    实验目的

    构造LR分析程序,利用它进行语法分析,判断给出的符号串是否为该文法识别的句子,了解LR(K)分析方法是严格的从左向右扫描,和自底向上的语法分析方法。

    实验内容

    对下列文法,用SLR(1)分析法对任意输入的符号串进行分析: 

    (1)S->E

    (2)E->E+T

    (3)E->T

    (4)T->T*F

    (5)T->F

    (6)F->(E)

    (7)F->i

    设计思想

    (1)总控程序,也可以称为驱动程序。对所有的LR分析器总控程序都是相同的。

    (2)分析表或分析函数,不同的文法分析表将不同,同一个文法采用的LR分析器不同时,分析表将不同,分析表又可以分为动作表(ACTION)和状态转换(GOTO)表两个部分,它们都可用二维数组表示。

    (3)分析栈,包括文法符号栈和相应的状态栈,它们均是先进后出栈。

    分析器的动作就是由栈顶状态和当前输入符号所决定。

    u LR分析器由三个部分组成:

    u 其中:SP为栈指针,S[i]为状态栈,X[i]为文法符号栈。状态转换表用GOTO[i,X]=j表示,规定当栈顶状态为i,遇到当前文法符号为X时应转向状态j,X为终结符或非终结符。

    u ACTION[i,a]规定了栈顶状态为i时遇到输入符号a应执行。动作有四种可能:

    (1)移进:

        action[i,a]= Sj:状态j移入到状态栈,把a移入到文法符号栈,其中i,j表示状态号。

    (2)归约:

        action[i,a]=rk:当在栈顶形成句柄时,则归约为相应的非终结符A,即文法中有A- B的产生式,若B的长度为R(即|B|=R),则从状态栈和文法符号栈中自顶向下去掉R个符号,即栈指针SP减去R,并把A移入文法符号栈内,j=GOTO[i,A]移进状态栈,其中i为修改指针后的栈顶状态。

    (3)接受acc:

        当归约到文法符号栈中只剩文法的开始符号S时,并且输入符号串已结束即当前输入符是'#',则为分析成功。

    (4)报错:

    当遇到状态栈顶为某一状态下出现不该遇到的文法符号时,则报错,说明输入端不是该文法能接受的符号串。

    【实验要求】

    1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。

    2、如果遇到错误的表达式,应输出错误提示信息。 

    3、程序输入/输出实例: 

    输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串 

    输出过程如下:

    步骤     状态栈     符号栈      剩余输入串            动 作  

     1          0             #          i+i*i#               移进 

    代码:

    #include<stdio.h>
    
    #include<stdlib.h>
    
    int Action[12][6] ={105, 0, 0, 104, 0, 0, 0, 106, 0, 0, 0, -1, 0, 52, 107, 0, 52, 52, 0, 54, 54, 0, 54, 54, 105, 0, 0, 104, 0, 0, 0, 56, 56, 0, 56, 56, 105, 0, 0, 104, 0, 0, 105, 0, 0, 104, 0, 0, 0, 106, 0, 0, 111, 0, 0, 51, 107, 0, 51, 51, 0, 53, 53, 0, 53, 53, 0, 55, 55, 0, 55, 55 };
    
    int Goto[12][3] ={1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 2, 3, 0, 0, 0, 0, 9, 3, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
    char Grammar[20][10] = { '' };
    
    char VT[10], VN[10];
    
    char AVT[6] = { 'i', '+', '*', '(', ')', '#' };
    
    char GVN[3] = { 'E', 'T', 'F' };
    
    int vnNum, vtNum, stateNum = 12;
    
    int VNum[10];
    
    int grammarNum;
    
    typedef struct{
    
    char *base;
    
    char *top;
    
    }SymbolStack;
    
     
    
    typedef struct{
    
    int *base;
    
    int *top;
    
    }StateStack;
    
     
    
    StateStack state;
    
    SymbolStack symbol;
    
     
    
    int ScanGrammar()
    
    {
    
    FILE *fp = fopen("D:SLR文法.txt","r");
    
    FILE *tp;
    
    char singleChar, nextChar;
    
    int i = 0, j = 0, k, count;
    
    while (!feof(fp))
    
    {
    
    fscanf(fp, "%c", &singleChar);
    
    if (singleChar == '?')
    
    {
    
    Grammar[i][j] = '';
    
    break;
    
    }
    
    if (singleChar == '
    ')
    
    {
    
    Grammar[i][j] = '';
    
    i++;
    
    j = 0;
    
    continue;
    
    }
    
    if (singleChar == '_')
    
    {
    
    tp = fp;
    
    fscanf(tp, "%c", &nextChar);
    
    if (nextChar == '>')
    
    {
    
    fp = tp;
    
    continue;
    
    }
    
    }
    
    if (singleChar == '|')
    
    {
    
    Grammar[i + 1][0] = Grammar[i][0];
    
    Grammar[i][j] = '';
    
    i++;
    
    j = 1;
    
    continue;
    
    }
    
    Grammar[i][j] = singleChar;
    
    if (singleChar >= 'A'&&singleChar <= 'Z'){
    
    count = 0;
    
    while (VN[count] != singleChar&&VN[count] != '')
    
    {
    
    count++;
    
    }
    
    if (VN[count] == '')
    
    {
    
    vnNum = count + 1;
    
    if (singleChar == 'S')
    
    {
    
    j++;
    
    continue;
    
    }
    
    VN[count] = singleChar;
    
    vnNum = count + 1;
    
    }
    
    }
    
    else
    
    {
    
    count = 0;
    
    while (VT[count] != singleChar&&VT[count] != '')
    
    {
    
    count++;
    
    }
    
    if (VT[count] == '')
    
    {
    
    VT[count] = singleChar;
    
    vtNum = count + 1;
    
    }
    
    }
    
    j++;
    
    }
    
    printf("输入的文法:
    ");
    
    for (k = 0; k <= i; k++)
    
    {
    
    j = 0;
    
    while (Grammar[k][j] != '')
    
    {
    
    if (j == 1)
    
    {
    
    printf("_>");
    
    }
    
    printf("%c", Grammar[k][j]);
    
    j++;
    
    }
    
    printf("
    ");
    
    }
    
    count = 0;
    
    printf("VT:");
    
    while (VT[count] != '')
    
    {
    
    printf("%3c", VT[count]);
    
    count++;
    
    }
    
    VT[count] = '#';
    
    vtNum = count + 1;
    
    printf("%3c", VT[count]);
    
    printf("
    VN:");
    
    count = 0;
    
    while (VN[count] != '')
    
    {
    
    printf("%3c", VN[count]);
    
    count++;
    
    }
    
    printf("
    ");
    
    // printf("
    %d %d
    ", vtNum, vnNum);
    
    fclose(fp);
    
    grammarNum = i + 1;
    
    return i;
    
    }
    
     
    
    int vNumCount()
    
    {
    
    int i,j;
    
    for (i = 0; i < grammarNum; i++)
    
    {
    
    j = 1;
    
    while (Grammar[i][j] != '')
    
    {
    
    j++;
    
    }
    
    VNum[i]=j;
    
    //printf("%3d", VNum[i]);
    
    }
    
    printf("
    ");
    
    return 0;
    
    }
    
     
    
    void InitStack()
    
    {
    
    state.base = (int *)malloc(100 * sizeof(int));
    
    if (!state.base)exit(1);
    
    state.top = state.base;
    
    *state.top = 0;
    
    symbol.base = (char*)malloc(100 * sizeof(char));
    
    if (!symbol.base)exit(1);
    
    symbol.top = symbol.base;
    
    *symbol.top = '#';
    
    }
    
     
    
    int Judge(int stateTop, char inputChar)
    
    {
    
     
    
        int i,j;
    
    for (i = 0; i < stateNum; i++){
    
    if (stateTop == i)break;
    
    }
    
    for (j = 0; j < vtNum; j++){
    
    if (inputChar == AVT[j])break;
    
    }
    
        return Action[i][i];
    
    }
    
     
    
    int GetGoto(int stateTop, char inputChar){
    
    int i, j;
    
    for (i = 0; i < stateNum; i++){
    
    if (stateTop == i) break;
    
    }
    
    for (j = 0; j < vnNum; j++)
    
    {
    
    if (inputChar == GVN[j]) break;
    
    }
    
    return Goto[i][j];
    
    }
    
     
    
    int print(int count, int i, char Input[], int action, int gt, int sign)
    
    {
    
    int *p = state.base, stateNum;
    
    int j, jj;
    
    char *q = symbol.base, symbolNum;
    
    printf("%d	", count);
    
    while (p != state.top + 1)
    
    {
    
    stateNum = *p;
    
    printf("%d", stateNum);
    
    p++;
    
    }
    
    printf("	");
    
    while (q != symbol.top + 1)
    
    {
    
    symbolNum = *q;
    
    printf("%c", symbolNum);
    
    q++;
    
    }
    
    printf("	");
    
    j = i;
    
    jj = 0;
    
    while (jj < j)
    
    {
    
    printf(" ");
    
    jj++;
    
    }
    
    while (Input[j] != '')
    
    {
    
    printf("%c", Input[j]);
    
    j++;
    
    }
    
    printf("	");
    
    if (sign == 1)
    
    {
    
    printf("	S%d	%d
    ", action, gt);
    
    }
    
    if (sign == 2)
    
    {
    
    printf("	r%d	%d
    ", action, gt);
    
    }
    
    if (sign == 3)
    
    {
    
    printf("tacc	%d
    ", gt);
    
    }
    
    if (sign == 0) printf("	0	0
    ");
    
    return 0;
    
    }
    
     
    
    int Pop(int action)
    
    {
    
    int *p, stateNumn, ssValue, i;
    
    state.top--;
    
    p = state.top;
    
    stateNum = *p;
    
    i = VNum[action] - 1;
    
    while (i != 0)
    
    {
    
    symbol.top--;
    
    i--;
    
    }
    
    symbol.top++;
    
    *symbol.top = Grammar[action][0];
    
    ssValue=GetGoto(stateNum,Grammar[action][0]);
    
    if (ssValue == 0)return ssValue;
    
    state.top++;
    
    *state.top = ssValue;
    
    return ssValue;
    
    }
    
     
    
    int Reduction()
    
    {
    
    char Input[20];
    
    int i = 0,count = 1;
    
    int ssValue, action;
    
    int stateTop, gt;
    
    int sign = -1; // 彩进1, 规约2, 接受3
    
    scanf("%s", &Input);
    
    while (Input[i] != '')
    
    {
    
    if (Input[i] >= 'A'&&Input[i] <= 'Z')
    
    {
    
    printf("输入的不是有效的表达式!");
    
    return 0;
    
    }
    
    i++;
    
    }
    
    i = 0;
    
    printf("步骤	状态栈	符号栈	输入串		ACTION	GOTO
    ");
    
    while (Input[i] != '')
    
    {
    
    if (count == 1)
    
    {
    
    print(count, i, Input, 0, 0, 0);
    
    count++;
    
    }
    
    stateTop = *state.top;
    
    ssValue = Judge(stateTop, Input[i]);
    
    if (ssValue == 0)
    
    {
    
    state.top--;
    
    if (*symbol.top == '#')
    
    {
    
    printf("规约出错!");
    
    return 0;
    
    }
    
    continue;
    
    }
    
    if (ssValue == -1)
    
    {
    
    sign = 3;
    
    print(count, i, Input, ssValue, 0, sign);
    
    count++;
    
    return 1;
    
    }
    
    if (ssValue >= 100)
    
    {
    
    sign = 1;
    
    action = ssValue - 100;
    
    state.top++;
    
    *state.top = action;
    
    symbol.top++;
    
    *symbol.top = Input[i];
    
    i++;
    
    print(count, i, Input, action, 0, sign);
    
    count++;
    
    }
    
    if (ssValue >= 50 && ssValue < 100)
    
    {
    
    sign = 2;
    
    action = ssValue - 50;
    
    gt = Pop(action);
    
    print(count, i, Input, action, gt, sign);
    
    count++;
    
    }
    
    }
    
    return 0;
    
    }
    
     
    
    int main()
    
    {
    
    ScanGrammar();
    
    vNumCount();
    
    InitStack();
    
    Reduction();
    
    return 0;
    
    }
    

      

    截图

     

  • 相关阅读:
    Ubuntu配置sublime text 3的c编译环境
    ORA-01078错误举例:SID的大写和小写错误
    linux下多进程的文件拷贝与进程相关的一些基础知识
    ASM(四) 利用Method 组件动态注入方法逻辑
    基于Redis的三种分布式爬虫策略
    Go语言并发编程总结
    POJ2406 Power Strings 【KMP】
    nyoj 会场安排问题
    Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor.
    Java的String、StringBuffer和StringBuilder的区别
  • 原文地址:https://www.cnblogs.com/dixingchen/p/14201070.html
Copyright © 2011-2022 走看看