语法分析

实验三、语法分析实验

 

一、        实验目的

(1)        编制一个语法分析程序

(2)        语法分析是在词法分析的基础上进行编写的,主要任务是根据词法分析出的种别码来判断。

(3)        通过语法分析的练习,能够进一步了解编译原理。

(4)        通过了解语法分析程序的设计原则、单词的描述技术、识别机制及语法分析程序的自动构造原理。

 

二、        实验内容和要求

(1)      以词法分析生成的单词符号序列作为输入

(2)      根据语言的语法规则,识别出各种语法成分

表达式、赋值语句、程序段等

(3)      并在分析过程中进行语法检查,检查所给的单词符号序列是否是该语言的一个句子

(4)      某种形式的语法树作为输出或报告错误

 

三、        实验方法、步骤及结果测试

1、实验方法、步骤:

²  自上而下分析法

³   如果文法有左递归?

³   如果文法不是LL(1)文法?

³   非确定的,穷举试探

³   确定的, 没有回溯

® 如何判断是否是LL(1)文法?

® 要求是LL(1)文法

® 文法改写为LL(1)文法

²  自下而上分析法

 

 

 

2、原理分析:我本来的词法分析程序是利用链队列(好处:先进先出且不浪费存储空间)进行存储用户输入字符串,以回车键结束,可当我用到语法分析程序的时候,我就发现了很多问题(暂时还没解决),所以我就改了一个简单的词法分析程序,以适应语法分析程序,这次我是用了一个二维数组来存储用户输入的字符串,每次只取一个字符(syn)进行语法分析。

 

void E()
{
    printf("E ");
    T();E1();
}
void E1()
{
    printf("E1 ");
    if (syn==13||syn==14) {
        scaner();
        T();E1();
    }
    else {
        if (syn!=28 && syn!=25) error();
    }
}
void T()
{
    printf("T ");
    F();T1();
}
void T1()
{
    printf("T1 ");
    if (syn==15||syn==16) {
        scaner();
        F();T1();
    }
    else {
        if (syn!=28 && syn!=25 && syn!=13&&syn!=14) error();
    }
}
void F()
{
    printf("F ");
    if (syn==27) {
        scaner();
        E();
        if(syn==28) scaner();
        else error();
    }
    else if (syn==11 || syn==10) scaner();

}

四、实验总结

这次的实验有点赶,因为我之前是用链队列来进词法分析程序的,由于这种方法应用到语法分析程序中就有点问题了,

所以我就临时改了一个简单的词法分析程序,这次我是用数组来存储用户输入的字符串,这样的好处是编写简单,清

晰明了,可也有它的不足之处,例如存储空间是固定的,没有灵活性。

#include <stdio.h>
//#include <string.h>
#define M 100
#define N 20
char str[M], wrong[N];
char ch;
int syn,t,m,n,sum;
char *keyword[6]= {"begin","if","then","while","do","end"};
void scaner();
void error();
void E();
void T();
void E1();
void F();
void T1();
main()
{
    char c;
    t=0;
    printf("Please input the arithmetic expressions: ");
    do{
         ch=getchar();
         str[t++]=ch;
    }while (ch!='=');
    t=0;
    do{
      scaner();
      switch(syn)
              {
                 case 11: printf("\n(%d,%d)",syn,sum); break;
                 case -1: printf("\n(%s,mistake)",wrong);break;
                 default: printf("\n(%d,%s)",syn, wrong);
              }
    }while (syn!=25);
    getchar();
    printf("\nWheter or not choice output grammer(y|n):");
    scanf("%c",&c);
    if(c=='Y'||c=='y'){
        t=0;
        scaner();
         E();
         if (syn==25)
                printf("\nGrammer correct\n");
         else     printf("\nGrammer mistake\n");
    }
}
void scaner()
{
        for (n=0;n<20;n++) wrong[n]=NULL;
        m=0;
        sum=0;
        ch=str[t++];
        while (ch==' ') {ch=str[t++];}
        if (ch>='a'&& ch<='z')
           {while (ch>='a'&& ch<='z'||ch>='0' && ch<='9')
                  {
                   wrong[m++]=ch;
                   ch=str[t++];
                  }

            syn=10;t--;
            for (n=0;n<6;n++)
                if(strcmp(wrong,keyword[n])==0) {syn=n+1;break;}
           }
 else
            if(ch>='0' && ch<='9')
            {while (ch>='0' && ch<='9') {sum=sum*10+(ch-'0'); ch=str[t++];}
             syn=11;t--;
            }
          else
                switch(ch)
                {
                  case '<': wrong[m++]=ch;
                            ch=str[t++];
                            if (ch=='>') {syn=21;wrong[m++]=ch;}
                            else if (ch=='=') {syn=22;wrong[m++]=ch;}
                                 else {syn=20;t--;}
                            break;

                  case '>': m=0; wrong[m++]=ch;
                            ch=str[t++];
                            if (ch=='='){syn=24;wrong[m++]=ch;}
                            else {syn=23;t--;}
                            break;
                  case ':': m=0; wrong[m++]=ch;
                            ch=str[t++];
                            if (ch=='='){syn=18;wrong[m++]=ch;}
                            else {syn=17;t--;}
                            break;
                  case '+': syn=13;wrong[0]=ch;break;
                  case '-': syn=14;wrong[0]=ch;break;
                  case '*': syn=15;wrong[0]=ch;break;
                  case '/': syn=16;wrong[0]=ch;break;
                  case '(': syn=27;wrong[0]=ch;break;
                  case ')': syn=28;wrong[0]=ch;break;
                  case '=': syn=25;wrong[0]=ch;break;
                  case ';': syn=26;wrong[0]=ch;break;
                  default: syn=-1;wrong[0]=ch;
                }
}
void E()
{
    printf("E ");
    T();E1();
}
void E1()
{
    printf("E1 ");
    if (syn==13||syn==14) {
        scaner();
        T();E1();
    }
    else {
        if (syn!=28 && syn!=25) error();
    }
}
void T()
{
    printf("T ");
    F();T1();
}
void T1()
{
    printf("T1 ");
    if (syn==15||syn==16) {
        scaner();
        F();T1();
    }
    else {
        if (syn!=28 && syn!=25 && syn!=13&&syn!=14) error();
    }
}
void F()
{
    printf("F ");
    if (syn==27) {
        scaner();
        E();
        if(syn==28) scaner();
        else error();
    }
    else if (syn==11 || syn==10) scaner();

}
void error()
{
    printf("\n(%d,%s)mistake\n",syn, wrong);
}

 

posted @ 2016-12-29 22:32  218~陈笑璞  阅读(1186)  评论(0编辑  收藏  举报