zoukankan      html  css  js  c++  java
  • 语法分析

    实验三、语法分析实验

    一、        实验目的

    (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("
    (%d,%d)",syn,sum); break;
                     case -1: printf("
    (%s,mistake)",wrong);break;
                     default: printf("
    (%d,%s)",syn, wrong);
                  }
        }while (syn!=25);
        getchar();
        printf("
    Wheter or not choice output grammer(y|n):");
        scanf("%c",&c);
        if(c=='Y'||c=='y'){
            t=0;
            scaner();
             E();
             if (syn==25)
                    printf("
    Grammer correct
    ");
             else     printf("
    Grammer mistake
    ");
        }
    }
    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("
    (%d,%s)mistake
    ",syn, wrong);
    }
  • 相关阅读:
    DOM对象模型接口规范中的四个基本接口
    js中几种实用的跨域方法原理详解(转)
    关于ie6/7下的z-index
    Mysql++学习(五)------专用SQL结构
    Mysql++学习(四)------模板查询
    Mysql++学习(三)------举个栗子
    Mysql++学习(二)------Mysql++简述
    Mysql++学习(一)------mysql编译安装
    epoll模型实例
    锁、页类型
  • 原文地址:https://www.cnblogs.com/2647409627qq/p/6235018.html
Copyright © 2011-2022 走看看