語義分析


實驗四、語法分析實驗

 

一、        實驗目的

(1)        編制一個語義分析程序

(2)        語義分析程序是在語法分析程序的基礎上進行編寫的,主要任務是根據語法分析來插入中間代碼、語義規則以及生成四元式。

(3)        通過語義分析的練習,能夠進一步了解編譯原理。

(4)        通過了解語義分析程序的設計原則、語義規則的描述技術、識別機制及語義分析程序的自動構造原理。

 

二、        實驗內容和要求

(1)        根據語法分析程序進行改寫語義分析程序

(2)        根據語言的語義規則,插入中間代碼、語義規則以及生成四元式等

(3)        並在分析過程中進行語義檢查,四元式作為輸出或以某種形式的語法樹作報告錯誤

 

三、        實驗方法、步驟及結果測試

1、實驗方法、步驟:

完成靜態語義審查和處理

a)         上下文相關性審查

b)        類型匹配審查

c)         類型轉換

d)        如:s:=2*3.1416*r*(h+r);

                                                    i.              賦值語句的語義:計算賦值符號右邊表達式的值,送到賦值號左邊的變量中。

                                                  ii.              檢查賦值號左右兩邊的類型是否匹配

                                                iii.              根據賦值語句的語義,將它翻譯成四元式中間代碼

 

2、原理分析:我是在語法分析程序的基礎上進行修改的,是根據語法分析來插入中間代碼、制定語義規則以及生成四元式。

void S(){
    char y=str[t-1];int x;
    if(syn==10){
        scaner();
        if(syn==18){
            scaner(); x=E();printf("\n(':=',%d, ,%c)\n",x,y);
        }
    }
}
int E(){
    int x;printf("E ");
    x=T();return E1(x);
}
int E1(int x){
    int y;printf("E1 ");
    if (syn==13) {
        scaner();
        y=T();gen4('+',x,y);return E1(x+y);
    }else if (syn==14) {
        scaner();y=T();gen4('-',x,y);return E1(x-y);
    }else {
        if (syn==28 || syn==25)return(x);
        else  error();
    }
}
int T(){
    int x;printf("T ");
    x=F();return T1(x);
}
int T1(int x){
    int y;printf("T1 ");
    if (syn==15) {
        scaner();y=F();gen4('*',x,y);return T1(x*y);
    }else if (syn==16) {
        scaner();y=F();gen4('/',x,y);return T1(x/y);
    }
    else {
        if (syn==28 ||syn==25 || syn==13||syn==14)return (x);
        else error();
    }
}
int F(){
    int y; printf("F ");
    if (syn==27) {
        scaner();y=E();
        if(syn==28) {scaner();return (y);
        }else error();
    }else if (syn==11 || syn==10){ y=sum; scaner();return (y);
    }
}

四、實驗總結

由於時間的關系,這次實驗我暫且做了語義分析的算術表達式與賦值語句,雖然做的不多,

但也算把算術表達式做的不錯,是有優先級的,我做的實驗是以’#’為結束語,輸出的四元式

是用(‘運算符’,操作數1,操作數2,運算結果);還有就是賦值語句是S:=E;這次實驗,

我學會了語法分析和語義分析程序,利用自上而下的遞歸下降分析法來分析語法,然后進行

賦予語義規則,再生產中間代碼,最后輸出四元式。

#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,s=100;
char *keyword[6]= {"begin","if","then","while","do","end"};
void scaner();
void error();
void gen4(char ch,int x,int y);
void S();
int E();
int T();
int E1(int x);
int F();
int T1(int x);
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!=0);
    getchar();
    printf("\nWheter or not choice output grammer(y|n):");
    scanf("%c",&c);
    if(c=='Y'||c=='y'){
        t=0;
        scaner();
        S();
         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;
                  case '#': syn=0;wrong[0]=ch;break;
                  default: syn=-1;wrong[0]=ch;
                }
}
void S()
{
    char y=str[t-1];int x;
    if(syn==10)
    {
        scaner();
        if(syn==18)
        {
            scaner();
            x=E();
              printf("\n(':=',%d, ,%c)\n",x,y);
        }
    }
}
int E()
{
    int x;
    printf("E ");
    x=T();return E1(x);
}
int E1(int x)
{
    int y;
    printf("E1 ");
    if (syn==13) {
        scaner();
        y=T();gen4('+',x,y);return E1(x+y);
    }else if (syn==14) {
        scaner();
        y=T();gen4('-',x,y);return E1(x-y);
    }
    else {
        if (syn==28 || syn==0)return(x);
        else  error();
    }
}
int T()
{
    int x;
    printf("T ");
    x=F();return T1(x);
}
int T1(int x)
{
    int y;
    printf("T1 ");
    if (syn==15) {
        scaner();

        y=F();gen4('*',x,y);return T1(x*y);

    }else if (syn==16) {
        scaner();

        y=F();gen4('/',x,y);return T1(x/y);
    }
    else {
        if (syn==28 ||syn==0 || syn==13||syn==14)return (x);
        else error();
    }
}
int F()
{
    int y;
    printf("F ");
    if (syn==27) {
        scaner();
        y=E();
        //gen4('+',x,y);return E1(x+y);
        if(syn==28) {scaner();return (y);
        }
        else error();
    }
    else if (syn==11 || syn==10){ y=sum; scaner();return (y);
    }
}
void error()
{
    printf("\n(%d,%s)mistake\n",syn, wrong);
}
void gen4(char ch,int x,int y)
{
    int z;
    float f;
    switch(ch){
    case '+':z=x+y;printf("\n('%c',%d,%d,%d)\n",ch,x,y,z);break;
    case '-':z=x-y;printf("\n('%c',%d,%d,%d)\n",ch,x,y,z);break;
    case '*':z=x*y;printf("\n('%c',%d,%d,%d)\n",ch,x,y,z);break;
    case '/':f=(float)x/y;printf("\n('%c',%d,%d,%0.1f)\n",ch,x,y,f);break;
    default:printf("mistakes!");
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM