編譯原理實驗之SLR1文法分析

---內容開始---ios

這是一份編譯原理實驗報告,分析表是手動造的,能夠做爲借鑑。git

基於  SLR(1) 分析法的語法制導翻譯及中間代碼生成程序設計原理與實現
1 、理論傳授
語法制導的基本概念,目標代碼結構分析的基本方法,賦值語句語法制導生成四元式的
基本原理和方法,該過程包括語法分析和語義分析過程。數組


2 、目標任務
[ 實驗 項目] 完成如下描述賦值語句 SLR(1)文法語法制導生成中間代碼四元式的過程。
G[A]:A→V=E
E→E+T∣E-T∣T
T→T*F∣T/F∣F
F→(E)∣i
V→i
 [ 設計說明 ] 終結符號 i 爲用戶定義的簡單變量,即標識符的定義。
 [ 設計要求] 數據結構

(1)構造文法的 SLR(1)分析表,設計語法制導翻譯過程,給出每一產生式
對應的語義動做;app

(2)設計中間代碼四元式的結構;函數

(3)輸入串應是詞法分析的輸出二元式序列,即某賦值語句「專題 1」的輸出結果,輸出爲賦值語句的四元式序列中間文件;測試

(4)設計兩個測試用例(儘量完備),並給出程序執行結果四元式序列。
 this

三、 程序功能描述spa

在第一次實驗詞法分析輸出結果的基礎上設計SLR1文法分析過程,並瞭解四元式的造成:翻譯

  1. 輸入串爲實驗一的二元式序列
  2. 輸出爲對輸入串的SLR(1)文法的判斷結果
  3. 輸出有針對輸入串的SLR(1)文法的具體分析過程
  4. 有對輸入串的四元式輸出序列

四、 主要數據結構描述

二元組結構體,用來存儲詞法分析程序輸出的二元組對 <類別,單詞>:

int count;

struct eryuanzu

{

int a;

char temp[COUNT];

}m[COUNT];

 

void out(int a,char* temp){// 打印二元組

 

printf("< %d %s >\n",a,temp);

m[count].a=a;

strcpy(m[count].temp,temp);  //

count++;

}

 

SLR1分析過程當中所要用到的狀態棧、符號棧等:

 

stack<int> state;           //狀態棧

stack<char> sign;           //符號棧

char st; //規約彈出時,狀態棧頂元素

int flag=0; //標誌是不是SLR

stack<string> place;        //變量地址棧

 

ACTION表,二維數組表示:

/* i  ( ) + - * / =  #

1開頭的百位數爲s移進項,0error-1accept,其他的一位兩位數是r規約項*/

int ACTION[20][9]={{103,0,0,0,0,0,0,0,0},//0

{0,0,0,0,0,0,0,0,-1},

{0,0,0,0,0,0,0,104,0},

{0,0,0,0,0,0,0,10,0},                                           

{109,108,0,0,0,0,0,0},

{0,0,0,110,111,0,0,0,1},//5 mnl;;huhyhjhjio

{0,0,4,4,4,112,113,0,4},

{0,0,7,7,7,7,7,0,7},

{109,108,0,0,0,0,0,0,0},

{0,0,9,9,9,9,9,0,9},

{109,108,0,0,0,0,0,0,0},//10

{109,108,0,0,0,0,0,0,0},

{109,108,0,0,0,0,0,0,0},

{109,108,0,0,0,0,0,0,0},

{0,0,119,110,111,0,0,0,0},

{0,0,2,2,2,112,113,0,2},//

{0,0,3,3,3,112,113,0,3},

{0,0,5,5,5,5,5,0,5},

{0,0,6,6,6,6,6,0,6},

{0,0,8,8,8,8,8,0,8}};//19

 

·GOTO表,二維數組表示:

//A V E T F

int GOTO[20][5]={{1,2,0,0,0},

{0,0,0,0,0},//1

{0,0,0,0,0},

{0,0,0,0,0},

{0,0,5,6,7},

{0,0,0,0,0},//5

{0,0,0,0,0},

{0,0,0,0,0},

{0,0,14,6,7},

{0,0,0,15,7},

{0,0,0,16,7},//10

{0,0,0,0,17},

{0,0,0,0,18},

{0,0,0,0,0},

{0,0,0,0,0},

{0,0,0,0,0},//15

{0,0,0,0,0},

{0,0,0,0,0},

{0,0,0,0,0},

{0,0,0,0,0}};//19

 

規約時所用到的函數,分別對應每一條規則:

void R1();          //AV=E

void R2();          //EE+T

void R3();          //EE-T

void R4();          //ET

void R5();          //TT*F

void R6();          //TT/F

void R7();          //TF

void R8();          //F(E)

void R9();          //Fi

void R10();         //Vi

 

void R1() {

 

 

 

sign.pop(); sign.pop(); sign.pop();       //彈出符號棧

 

state.pop(); state.pop(); state.pop();    //彈出狀態棧

 

sign.push('A');                         //符號'A'入棧

 

st=state.top();

 

printf("r1\t");

 

}

 

void R2() {

 

 

 

sign.pop(); sign.pop(); sign.pop();       //彈出符號棧

 

state.pop(); state.pop(); state.pop();    //彈出狀態棧

 

sign.push('E'); st=state.top();                        //符號'E'入棧

 

printf("r2\t\t");

 

}

 

void R3() {

 

 

 

sign.pop(); sign.pop(); sign.pop();

 

state.pop(); state.pop(); state.pop();

 

sign.push('E');st=state.top();

 

printf("r3\t\t");

 

}

 

void R4() {

 

sign.pop();

 

state.pop();

 

sign.push('E');st=state.top();

 

printf("r4\t\t");

 

}

 

void R5() {

 

 

 

sign.pop(); sign.pop(); sign.pop();

 

state.pop(); state.pop(); state.pop();

 

sign.push('T');st=state.top();

 

printf("r5\t\t");

 

}

 

void R6() {

 

 

 

sign.pop(); sign.pop(); sign.pop();

 

state.pop(); state.pop(); state.pop();

 

sign.push('T');st=state.top();

 

printf("r6\t\t");

 

}

 

void R7() {

 

sign.pop();

 

state.pop();

 

sign.push('T');st=state.top();

 

printf("r7\t\t");

 

}

 

void R8() {

 

sign.pop(); sign.pop(); sign.pop();

 

state.pop(); state.pop(); state.pop();

 

sign.push('F');st=state.top();

 

printf("r8\t\t");

 

}

 

void R9() {

 

sign.pop();

 

state.pop();

 

sign.push('F');st=state.top();

 

printf("r9\t\t");

 

}

 

void R10() {

 

sign.pop();

 

state.pop();

 

sign.push('V');st=state.top();

 

printf("r10\t\t");

 

}

 

SLR1分析處理函數:

 

void SLR()

{

printf("輸入串\t\t狀態棧\t\t符號棧\t\tACTION\t\tGOTO   ");

int i,j,k=1;

state.push(0); //初始化

sign.push('#');

int which;  //對應表項內容

char c; //輸入符號串首

int a; //座標

int b;

do{

printf("\n");

c=m[k-1].temp[0]; //輸入符號串首

cout<<c<<' ';

for(int j=k;j<=count;j++)

printf("%s",m[j].temp);

printf("\t\t");

displayStack(state);

 

displayStack1(sign);

a=state.top(); //座標

b=isVt(c);

/*if(isOp(c)!=-1)

temp1=c;

place.push(temp1);*/

if(b!=-1)  //輸入串首c是終結符

{

 

which=ACTION[a][b];

if(which==-1)

{

printf(" acc,分析成功!\n");

flag=1;

break;

}

else if(which==0)

{ printf("error1\n ");break; }

else if(which>=100) //移進

{

which=s_r(which);

printf("s%d\t\t",which);

sign.push(c);

state.push(which);

k++;

}

else

{

switch(which) //which整型,case不要加''

{                                                                                                                                                                                                                                                        

case 1:R1();break;

case 2:R2();break;

case 3:R3();break;

case 4:R4();break;

case 5:R5();break;

case 6:R6();break;

case 7:R7();break;

case 8:R8();break;

case 9:R9();break;

case 10:R10();break;

default:printf("which=%derror2\n ");break;

}

//狀態轉移 Vn

int e=isVn(sign.top());

if(e!=-1)

{

int convert=GOTO[st][e];

state.push(convert);

printf("GOTO[%d,%c]=%d",st,sign.top(),convert);

}

}

}

else   

{ printf("error_b ");break; }

 

}while(which!=-1);//while

}

 五、實驗測試

1.測試用例:i=(i-i*i)#,輸入file.txt直接從文件讀取輸入串,獲得結果以下:

 

四元式結果輸出:

 因爲圖片沒法上傳便罷

六、 實驗總結 

本次實驗是對理論課上所學知識的應用,重點是理解分析棧和符號棧,這裏我採用自行造ACTION和GOTO表,這樣SLR分析表就出來了,自動造表仍是比較複雜。並且在造表的過程當中常常出錯,最後在你們的討論中解決了。造完表後的分析過程並不複雜,循序漸進分狀況來處理。

本次實驗加深了我對SLR1的分析過程的理解,也加深了對四元式的認識。

 七、源代碼

分爲兩個CPP

Siyuanshi.cpp   

#include "stdafx.h"
#include<stdlib.h>
#include<fstream>
#include<iostream>
#include<stdio.h>
using namespace std;

#define MAX 100
int mm=0,sum=0;//sum用於計算運算符的個數
                  //mm用於標輸入表達式中字符的個數
char JG='A';
char str[MAX];//用於存輸入表達式
int  token=0;//左括號的標誌

/***********用於更改計算後數組中的值**************/
void change(int e)
{
    int f=e+2;
    char ch=str[f];    
    if(ch>='A'&&ch<='Z')
    {
        for(int l=0;l<mm+10;l++)
        {
            if(str[l]==ch)
                str[l]=JG;
        }
    }
    
    if(str[e]>='A'&&str[e]<='Z')
    {
        for(int i=0;i<mm;i++)
        {
            if(str[i]==str[e])
                str[i]=JG;
        }
    }    
}


void chengchuchuli(int i,int mm)
{
    
    i++;
    for( ;i<=mm-1;i++)//處理乘除運算
    {
       if(str[i]=='*'||str[i]=='/') 
       {
           
           cout<<"("<<str[i]<<" "<<str[i-1]<<"  "<<str[i+1]<<"  "<<JG<<")"<<endl;
           change(i-1);
           str[i-1]=str[i]=str[i+1]=JG;
           sum--;
           JG=(char)(int)JG++;
       }
    }
}

void jiajianchuli(int j,int mm)
{
    j++;
    for( ;j<=mm-1;j++)//處理加減運算
    {
       if(str[j]=='+'||str[j]=='-') 
       {
           cout<<"("<<str[j]<<" "<<str[j-1]<<"  "<<str[j+1]<<"  "<<JG<<")"<<endl;
           change(j-1);
           str[j-1]=str[j]=str[j+1]=JG;
           sum--;
           JG=(char)(int)JG++;
       }       
    }
}

/*掃描遍從文件中讀入表達式*/
void scan(FILE *fin)
{   
        int p[MAX];
        char ch='a';
        int c=-1,q=0;
        while(ch!=EOF)
        {
            ch=getc(fin);

            while(ch==' '||ch=='\n'||ch=='\t') 
                ch=getc(fin);//消除空格和換行符
            
            str[mm++]=ch;
            if(ch=='='||ch=='+'||ch=='-'||ch=='*'||ch=='/') 
                sum++;
            else if(ch=='(') 
            {
                p[++c]=mm-1;
            }
            else if(ch==')')
            {
                  q=mm-1;
                  chengchuchuli(p[c],q);//從左括號處理到又括號
                  jiajianchuli(p[c],q);                 
                  JG=(char)(int)JG--;
                  str[p[c]]=str[mm-1]=JG;
                  c--;
                  JG=(char)(int)JG++;      
            }
        }
}    

void siyuanshi()
{

    for(int i=0;i<=mm-1;i++)//處理乘除運算
    {
       if(str[i]=='*'||str[i]=='/') 
       {
           
           cout<<"("<<str[i]<<"  "<<str[i-1]<<"  "<<str[i+1]<<"  "<<JG<<")"<<endl;
           change(i-1);
           str[i-1]=str[i]=str[i+1]=JG;
           sum--;
           JG=(char)(int)JG++;
       }
    
    }

    for(int j=0;j<=mm-1;j++)//處理加減運算
    {
       if(str[j]=='+'||str[j]=='-') 
       {
           
           cout<<"("<<str[j]<<"  "<<str[j-1]<<"  "<<str[j+1]<<"  "<<JG<<")"<<endl;
           change(j-1);
           str[j-1]=str[j]=str[j+1]=JG;
           sum--;
           JG=(char)(int)JG++;
       }
    
    } 
    
    for(int k=0;k<=mm-1;k++)//處理賦值運算
    {
       if(str[k]=='=') 
       {
           
           JG=(char)(int)--JG;
           cout<<"("<<str[k]<<"  "<<str[k+1]<<"  "<<"  "<<" "<<str[k-1]<<")"<<endl;
           sum--;
           change(k+1);
           str[k-1]=JG;
       }
    }

}

extern void MAIN(){
    char in[MAX]; //用於接收輸入輸出文件名
    FILE *fin; 
    cout<<"請輸入源文件名(包括後綴名)"<<endl;
    cin>>in;;
    if ((fin=fopen(in,"r"))==NULL) 
    {
      cout<<"error"<<endl;
    }
    cout<<"*********四元式以下*********"<<endl;
    scan(fin);//調用函數從文件中讀入表達式     
    siyuanshi();
    if(sum==0) printf("成功?");
    else printf("有錯誤");
    //關閉文件
    fclose(fin);
    system("pause");
}

 

Bianyi_5.cpp

// bianyi_5.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <stack>
#include <map>
#include <string>
#include <cstring>
#include <iomanip>

using namespace std;
extern void MAIN();
#define ADD 1
#define SUB 2
#define MUL 3
#define FH 4
#define SG 5
#define ID 6
#define INT 7
#define LT 8
#define LE 9
#define EQ 10
#define NE 11
#define GT 12
#define GE 13
#define MHEQ 14
#define XGMUL 15
#define ZKH 16
#define YKH 17
#define DIV 18 
#define EQ 19//=
#define blz 00

#define COUNT 40 
char* keyword[]={"begin","end","if","then","else","for","do","and","or","not"};//保留字

int count;
struct eryuanzu
{
    int a;
    char temp[COUNT];
}m[COUNT];

void out(int a,char* temp){// 打印二元組

    printf("< %d %s >\n",a,temp);
    m[count].a=a;
    strcpy(m[count].temp,temp);  //
    count++;
}

stack<int> state;           //狀態棧
stack<char> sign;           //符號棧
char st; //規約彈出時,狀態棧頂元素
int flag=0; //標誌是不是SLR
stack<string> place;        //變量地址棧

                            
/*                    i  ( ) + - * / =  #
以1開頭的百位數爲s移進項,0爲error,-1爲accept,其他的一位或兩位數是r規約項*/
int ACTION[20][9]={{103,0,0,0,0,0,0,0,0},//0
                    {0,0,0,0,0,0,0,0,-1},
                    {0,0,0,0,0,0,0,104,0},
                    {0,0,0,0,0,0,0,10,0},                                                                                                                                                                                                                      
                    {109,108,0,0,0,0,0,0},
                    {0,0,0,110,111,0,0,0,1},//5 
                    {0,0,4,4,4,112,113,0,4},
                    {0,0,7,7,7,7,7,0,7},
                    {109,108,0,0,0,0,0,0,0},
                    {0,0,9,9,9,9,9,0,9},
                    {109,108,0,0,0,0,0,0,0},//10
                    {109,108,0,0,0,0,0,0,0},
                    {109,108,0,0,0,0,0,0,0},
                    {109,108,0,0,0,0,0,0,0},
                    {0,0,119,110,111,0,0,0,0}, 
                    {0,0,2,2,2,112,113,0,2},//
                    {0,0,3,3,3,112,113,0,3},
                    {0,0,5,5,5,5,5,0,5},
                    {0,0,6,6,6,6,6,0,6},
                    {0,0,8,8,8,8,8,0,8}};//19
//A V E T F
int GOTO[20][5]={{1,2,0,0,0},
                {0,0,0,0,0},//1
                {0,0,0,0,0},
                {0,0,0,0,0},
                {0,0,5,6,7},
                {0,0,0,0,0},//5
                {0,0,0,0,0},
                {0,0,0,0,0},
                {0,0,14,6,7},
                {0,0,0,15,7},
                {0,0,0,16,7},//10
                {0,0,0,0,17},
                {0,0,0,0,18},
                {0,0,0,0,0},
                {0,0,0,0,0},
                {0,0,0,0,0},//15
                {0,0,0,0,0},
                {0,0,0,0,0},
                {0,0,0,0,0},
                {0,0,0,0,0}};//19

void R1();          //A→V=E
void R2();          //E→E+T
void R3();          //E→E-T
void R4();          //E→T
void R5();          //T→T*F
void R6();          //T→T/F
void R7();          //T→F
void R8();          //F→(E)
void R9();          //F→i
void R10();         //V→i

int isOp(char a)  //判斷二元運算符及二元運算符的優先級
{
    int i;
    switch(a)
    {
    case '=':i=0;break;
    case '+':i=1;break;
    case '-':i=1;break;
    case '*':i=2;break;
    case '/':i=2;break;
    default:i=-1;break;
    }
    return i;
}
int isVt(char a)
{
    int i;
    switch(a)
    {
    case 'i':i=0;break;
    case '(':i=1;break;
    case ')':i=2;break;
    case '+':i=3;break;
    case '-':i=4;break;
    case '*':i=5;break;
    case '/':i=6;break;
    case '=':i=7;break;
    case '#':i=8;break;
    default:i=-1;break;
    }
    return i;
}
int isVn(char a)
{
    int i;
    switch(a)
    {
    case 'A':i=0;break;
    case 'V':i=1;break;
    case 'E':i=2;break;
    case 'T':i=3;break;
    case 'F':i=4;break;
    default:i=-1;break;
    }
    return i;
}
int s_r(int i)  //移進或者其餘
{
    int result;
    if(i/100==1)    //移進
        result=i-100;
    else
        result=i;  
    return result;
}

bool invertStack(stack<int> &one_stack) 
{
    if (one_stack.empty())//if the stack is null,then don't invert it
    {
        return false;
    }
    else
    {
        //init a stack to save the inverted stack
        stack<int> invert;
        while (!one_stack.empty())
        {
            invert.push(one_stack.top());
            one_stack.pop();
        }
        //this moment the stack's inverted state is the stack invert ,so get it back
        one_stack = invert;
        return true;
    }
}

void displayStack(stack<int> one_stack) //打印輸出
{
    invertStack(one_stack);
    while (!one_stack.empty())
    {
        cout << one_stack.top();
        one_stack.pop();
    }
    cout << '\t' << '\t' ;
}

bool invertStack1(stack<char> &one_stack)
{
    if (one_stack.empty())//if the stack is null,then don't invert it
    {
        return false;
    }
    else
    {
        //init a stack to save the inverted stack
        stack<char> invert;
        while (!one_stack.empty())
        {
            invert.push(one_stack.top());
            one_stack.pop();
        }
        //this moment the stack's inverted state is the stack invert ,so get it back
        one_stack = invert;
        return true;
    }
}

void displayStack1(stack<char> one_stack)
{
    invertStack1(one_stack);
    while (!one_stack.empty())
    {
        cout << one_stack.top();
        one_stack.pop();
    }
    cout << '\t' << '\t';
}

void SLR()
{
    printf("輸入串\t\t狀態棧\t\t符號棧\t\tACTION\t\tGOTO   ");
    int i,j,k=1;
    state.push(0); //初始化
    sign.push('#'); 
    int which;  //對應表項內容
    char c; //輸入符號串首
    int a; //座標
    int b;
do{
    printf("\n");    
    c=m[k-1].temp[0]; //輸入符號串首
    cout<<c<<' ';
    for(int j=k;j<=count;j++)
        printf("%s",m[j].temp);
    printf("\t\t");
    displayStack(state);
        
    displayStack1(sign);
    a=state.top(); //座標
    b=isVt(c);
    /*if(isOp(c)!=-1)
        temp1=c;
    place.push(temp1);*/
    if(b!=-1)  //輸入串首c是終結符
    {
        
        which=ACTION[a][b];
        if(which==-1)
        {
            printf(" acc,分析成功!\n");
            flag=1;
            break;
        }
        else if(which==0)
        {    printf("error項1\n ");break;    }
        else if(which>=100) //移進
        {
            which=s_r(which);
            printf("s%d\t\t",which);
            sign.push(c);
            state.push(which);
            k++;
        }
        else 
        {
            switch(which) //which整型,case不要加''
            {                                                                                                                                                                                                                                                        
            case 1:R1();break;
            case 2:R2();break;
            case 3:R3();break;
            case 4:R4();break;        
            case 5:R5();break;
            case 6:R6();break;
            case 7:R7();break;
            case 8:R8();break;
            case 9:R9();break;
            case 10:R10();break;
            default:printf("which=%derror項2\n ");break;
            }    
            //狀態轉移 Vn
            int e=isVn(sign.top());
            if(e!=-1)
            {
            int convert=GOTO[st][e];
            state.push(convert);
            printf("GOTO[%d,%c]=%d",st,sign.top(),convert);
            }
        }
    }
    else   
    {    printf("error_b ");break;    }
    
}while(which!=-1);//while
}

void R1() {
    
    sign.pop(); sign.pop(); sign.pop();       //彈出符號棧
    state.pop(); state.pop(); state.pop();    //彈出狀態棧
    sign.push('A');                         //符號'A'入棧
    st=state.top();
    printf("r1\t");
}
void R2() {
    
    sign.pop(); sign.pop(); sign.pop();       //彈出符號棧
    state.pop(); state.pop(); state.pop();    //彈出狀態棧
    sign.push('E'); st=state.top();                        //符號'E'入棧
    printf("r2\t\t");
}
void R3() {

    sign.pop(); sign.pop(); sign.pop();
    state.pop(); state.pop(); state.pop();
    sign.push('E');st=state.top();
    printf("r3\t\t");
}
void R4() {
    sign.pop();
    state.pop();
    sign.push('E');st=state.top();
    printf("r4\t\t");
}
void R5() {

    sign.pop(); sign.pop(); sign.pop();
    state.pop(); state.pop(); state.pop();
    sign.push('T');st=state.top();
    printf("r5\t\t");
}
void R6() {

    sign.pop(); sign.pop(); sign.pop();
    state.pop(); state.pop(); state.pop();
    sign.push('T');st=state.top();
    printf("r6\t\t");
}
void R7() {
    sign.pop();
    state.pop();
    sign.push('T');st=state.top();
    printf("r7\t\t");
}
void R8() {
    sign.pop(); sign.pop(); sign.pop();
    state.pop(); state.pop(); state.pop();
    sign.push('F');st=state.top();
    printf("r8\t\t");
}
void R9() {
    sign.pop();
    state.pop();
    sign.push('F');st=state.top();
    printf("r9\t\t");
}
void R10() {
    sign.pop();
    state.pop();
    sign.push('V');st=state.top();
    printf("r10\t\t");
}

///////////////////////////////////////////////
void scanner(FILE *p)
{    
    char filein[40],fileout[40]; //文件名
    printf("請輸入要打開的源文件名(包括路徑)\n");
    scanf("%s",filein);
    //printf("請輸入要輸出的目標文件名(包括路徑)\n");
    //scanf("%s",fileout);
    if((p=fopen(filein,"r"))==NULL) {printf("輸入文件打開有錯!\n");return;}
//    if((q=fopen("fileout","rw"))==NULL) {printf("輸出文件打開有錯!\n");return;}

    char token[COUNT]; //輸出數組
    int r=0,i=0;
    char ch;    
    ch=fgetc(p);
    while(!feof(p)) //沒有讀到文件末尾
{
    if(isdigit(ch))
    {
        i=0;
        token[i]=ch;
        while(isdigit(ch=fgetc(p)))
        {
            i++;
            token[i]=ch;
        }
        token[i+1]='\0'; //整數結束。不要忘結束標誌!
        fseek(p,-1,1); //重定向到當前位置的前一個!
        out(INT,token);
        //fprintf(q,"%d %s\n",INT,token);
    }
    else if(isalpha(ch))
    {
        i=0;
        int flag=0; //標誌是不是保留字,默認不是
        token[i]=tolower(ch);
        while(isalpha(ch=fgetc(p)))
        {
            i++;
            token[i]=tolower(ch);
        }
        token[i+1]='\0'; 
        fseek(p,-1,1);
        for(r=0;r<8;r++)
        {
            if(!strcmp(token,keyword[r]))
            {
                printf("<blz %s>\n",token);
            //    fprintf(q,"%d %s\n","保留字",token);
                flag=1;
                break;
            }
        }    
        if(!flag)
        {    out(ID,token);    
        //    fprintf(q,"%d %s\n",ID,token);
        }
    }
    else
    {
        i=0;
        switch(ch)
        {
        case '+':{    token[i]=ch;
                    token[i+1]='\0'; 
                    out(ADD,token);    
                    }break;
        case '-':{    token[i]=ch;
                    token[i+1]='\0'; 
                    out(SUB,token);}break;
        case '*':{    token[i]=ch;
                    token[i+1]='\0'; 
                    out(MUL,token);}break;
        case ';':{    token[i]=ch;
                    token[i+1]='\0'; 
                    out(FH,token);}break;
        case '|':{    token[i]=ch;
                    token[i+1]='\0'; 
                    out(SG,token);}break;
        case '(':{    token[i]=ch;
                    token[i+1]='\0'; 
                    out(ZKH,token);}break;
        case ')':{    token[i]=ch;
                    token[i+1]='\0'; 
                    out(YKH,token);}break;
        case '=':{    token[i]=ch;
                    token[i+1]='\0'; 
                    out(EQ,token);}break;
        case ' ':{    break;} //空格直接跳
        case '#':{    break;} //井號用做結尾            
        case '<':{token[i]=ch;
                ch=fgetc(p);
                if(ch=='='){
                    token[i+1]='=';
                    token[i+2]='\0'; 
                    out(LE,token);
                }
                else if(ch=='>'){
                    token[i+1]='>';
                    token[i+2]='\0';
                    out(NE,token);
                }
                else 
                {    printf(" error \n");
                    fseek(p,-1,1);    //多讀的要回退一個字符
                }
                 }break;
                
        case '>':{token[i]=ch;
                ch=fgetc(p);
                if(ch=='=')
                {
                    token[i+1]='=';
                    token[i+2]='\0';
                    out(GE,token);
                }
                else 
                {    printf(" error \n");
                    fseek(p,-1,1);    //多讀的要回退一個字符
                }
                }break;
        case ':':{token[i]=ch;
                ch=fgetc(p);
                if(ch=='='){
                    token[i+1]='=';
                    token[i+2]='\0';
                    out(MHEQ,token);
                }
                else 
                {    printf(" error \n");
                    fseek(p,-1,1);    //多讀的要回退一個字符
                }
                 }break;
    case '/':{token[i]=ch;
                ch=fgetc(p);
                if(ch=='*')
                {    
                    token[i+1]='*';
                    token[i+2]='\0';
                    out(XGMUL,token);
                    while(1)    //註釋部分的處理!
                    {
                        ch=fgetc(p);
                        if(ch=='*')
                        {
                            if((ch=fgetc(p))=='/')
                                break;
                        }
                    }
                }
                else // 除號,修改第一次程序部分
                {    /*printf(" error \n");
                    fseek(p,-1,1);    */
                    out(DIV,token);
                    fseek(p,-1,1);//多讀的要回退一個字符
                }
                }break;
        default:{
                    printf(" error\n ");
                }break;
                    
        }
    }
    ch=fgetc(p);
}
    fclose(p);
}
int main(int argc, char* argv[])
{
    printf("編譯原理實驗_5:SLR分析程序(待分析內容在文件file.txt中,以#結尾)\n");
    FILE *fin,*q;
    scanner(fin);
    strcpy(m[count].temp,"#");//! 
    count=count+1;
    //scanner(p,q);
    SLR();
    MAIN();
    return 0;
}

 

 

---內容結束---

相關文章
相關標籤/搜索