实验二 LL(1)语法分析程序设计

目录

实验目的

实验内容

实验要求​​​​​​

运行结果示例

实验代码

运行结果


实验目的

         了解LL(1)分析器的基本构成及用自顶向下的LL(1)方法对表达式进行语法分析的方法,掌握LL(1)语法分析程序的构造方法。

实验内容

         根据LL(1)语法分析算法的基本思想,设计一个对给定文法进行LL(1)语法分析的程序,并用C语言编程实现。对于给定的输入串,能够识别该串是否位给定文法的句型。

实验要求​​​​​​

输入一个LL(1)文法,构造相应的预测分析表。

从键盘读入输入串,由算法判断输入串是否为该文法的句子,若正确,就通过,否则就报错。

运行结果示例

【参考说明】

语法分析主要是将从词法分析那里得来的记号构成一棵语法树。例:

SHMA#
 adbe# 
 S->aH
 H->aMd
 H->d
 M->Ab
 M->
 A->aM
 A->e

**************************************************************

LL(1)文法分析器运行结果:

分析例句:(需要显示合法和不合法两种情况)

例: 分析例句:aaabd#  

预测分析表输出:

……

aaabd# 是给定文法的句子

……

Ade#不是给定文法的句子

**************************************************************

运行成功以后,检查程序,并将运行结果截图打印粘贴到实验报告上。

实验代码

本实验的文法:

对给定文法G[E]:

E->TA

A->+TA | $

T->FB

B->*FB | $

F-> i | (E)

其中,$表示空串。

#include
#include
#include
#include
#include
using namespace std;
//#pragma warning(disable:4996)

//本文法参考教材81面文法,将E'替换为A,T'替换为B
//作为示范的句子有
//i+i*i#   (是文法的句子)
//i*i+i#   (是文法的句子)
//i*(i+i)#   (是文法的句子)
//i*)i+i#     (不是文法的句子)
//i+i+*i#     (不是文法的句子)

char Line[6] = "EATBF";//非终结符
char Row[7] = "i+*()#";//终结符

//表格数组,存储预测分析表
char ForcastTable[5][6][100] = { {"->TA","null" ,"null","->TA" ,"null","null" },
                                   {"null","->+TA" ,"null","null" ,"->$", "->$" },
                                   {"->FB","null" ,"null" ,"->FB","null","null" },
                                   {"null","->$" ,"->*FB" ,"null"  ,"->$","->$" },
                                   {"->i" ,"null","null","->(E)" ,"null","null" } };

stackS;

int FindLine(char a)//找非终结符
{
    for (int i = 0; i < 5; i++)
    {
        if (a == Line[i])
            return i;
    }
    return -1;
}

int FindRow(char b)//找终结符
{
    for (int i = 0; i < 6; i++)
    {
        if (b == Row[i])
            return i;
    }
    return -1;
}
//获得一个句子中#前的部分,如句子为i+i*i##,则返回i+i*i#
char* GetStr(char* s)
{
    char* p = strrchr(s, '#');//判断输入的是否含有'#'
    if (p != NULL)//含有,则截取前面到#的字符串
    {
        int i = 0;
        while (s[i] != '#')
        {
            i++;
        }
        char* str = new char[i + 2];
        strncpy(str, s, i + 1);//截取s中的前i+1个元素分给str
        str[i + 1] = '\0';
        return str;
    }
    return s;
}

void AnalyzeProcess(char str[], int len)
{
    int i = 0;      //索引str的字符
    while (true)
    {
        int x, y;
        char ch = S.top();
        if (ch >= 'A' && ch <= 'Z')   //判断是否为非终结符
        {
            S.pop();
            x = FindLine(ch);
            y = FindRow(str[i]);
            if (x != -1 && y != -1)//找到
            {
                // 输出匹配内容
                if (ForcastTable[x][y] == "null") //找到对于表为空
                {
                    printf("%s", str);
                    printf("%s\n\n", "不是给定文法的句子!");
                    exit(0);
                }
                else//找到信息
                {
                    for (int q = strlen(ForcastTable[x][y]) - 1; q > 1; q--)//逆序入栈,改变字符串
                    {
                        S.push(ForcastTable[x][y][q]);
                    }
                    if (strcmp(ForcastTable[x][y], "->$") == 0)
                    {
                        S.pop();
                    }
                }
            }
            else//未找到  
            {
                printf("%s", str);
                printf("%s\n\n", "不是给定文法的句子!");
                break;
            }
        }
        else//匹配串的第一个
        {
            if (ch == str[i])
            {

                S.pop();
                if (ch = '#' && str[i] == '#')
                {
                    printf("%s", str);
                    printf("%s\n\n", "是给定文法的句子!");
                    return;
                }
                i++;
            }
            else
            {
                printf("%s", str);
                printf("%s\n\n", "不是给定文法的句子!");
                return;
            }
        }
    }
}
//输出分析表,并且分析
void ShowFunc()
{
    printf("%s\n\n", "当前的预测分析表为:");
    printf("%s", " ");
    for (int a = 0; a < 6; a++)//输出预测分析表
    {
        printf("%5c", Row[a]);
    }
    printf("\n");
    for (int i = 0; i < 5; i++)
    {
        printf("%c", Line[i]);
        for (int j = 0; j < 6; j++)
        {
            printf("%6s", ForcastTable[i][j]);
        }
        printf("\n");
    }
    printf("%s\n\n", "请输入需要分析的语句,需要按quit/QUIT结束!");
    while (true)//输入quit时跳出循环,程序运行结束
    {
        char str[200];
        cin >> str;
        if (strcmp(str, "quit") == 0 || strcmp(str, "QUIT") == 0)
        {
            printf("欢迎下次使用!!!");
            return;
        }
        int len = strlen(GetStr(str));
        S.push('#');
        S.push('E');
        AnalyzeProcess(GetStr(str), len + 1);
    }
}

int main()
{
    //输出分析表,并按输入分析,按quit退出
    ShowFunc();
    return 0;
}

运行结果

先输出当前的预测分析表,然后输入待分析例句,给出相应结果分析结果,并输出,输入quit可以终止程序。

实验二 LL(1)语法分析程序设计_第1张图片

 欧克,这个实验代码就丢在这里了,希望可以帮助到后面的学习者,欢迎大家关注!

你可能感兴趣的:(c/c++相关,编辑器,c++,c语言)