编译原理实验之SLR1文法分析

时间:2022-06-20 07:04:24

---恢复内容开始---

这是一份编译原理实验报告,分析表是手动造的,可以作为借鉴。

基于  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)分析表,设计语法制导翻译过程,给出每一产生式
对应的语义动作;

(2)设计中间代码四元式的结构;

(3)输入串应是词法分析的输出二元式序列,即某赋值语句“专题 1”的输出结果,输出为赋值语句的四元式序列中间文件;

(4)设计两个测试用例(尽可能完备),并给出程序执行结果四元式序列。
 

3、 程序功能描述

在第一次实验词法分析输出结果的基础上设计SLR1文法分析过程,并了解四元式的形成:

  1. 输入串为实验一的二元式序列
  2. 输出为对输入串的SLR(1)文法的判断结果
  3. 输出有针对输入串的SLR(1)文法的具体分析过程
  4. 有对输入串的四元式输出序列

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

}

 5、实验测试

1.测试用例:i=(i-i*i)#,输入file.txt直接从文件读取输入串,得到结果如下:

 编译原理实验之SLR1文法分析

四元式结果输出:

 由于图片无法上传便罢

6、 实验总结 

本次实验是对理论课上所学知识的应用,重点是理解分析栈和符号栈,这里我采用自行造ACTION和GOTO表,这样SLR分析表就出来了,自动造表还是比较复杂。而且在造表的过程中经常出错,最后在大家的讨论中解决了。造完表后的分析过程并不复杂,按部就班分情况来处理。

本次实验加深了我对SLR1的分析过程的理解,也加深了对四元式的认识。

 7、源代码

分为两个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用于计算运算符的个数

                  //m用于标输入表达式中字符的个数

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;

   // scanf("%s",in);

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移进项,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

{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();          //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

 

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("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

}

 

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("编译原理实验_5SLR分析程序(待分析内容在文件file.txt中,以#结尾)\n");

FILE *fin,*q;

scanner(fin);

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

count=count+1;

//scanner(p,q);

SLR();

MAIN();

return 0;

}

 

---恢复内容结束---