每次由不同组员编写 未整合故无关联
in.txt
program test (a,b);
begin
x:=19;
y:=x+5*6;
if x<y then y:=x
else begin
while x+y<x do y:=y+1;
z:=z*7
end
end.
词法分析 _by GaHingZ
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<list>
#include <math.h>
#include <windows.h>
#define BOOL int
#define TRUE 1
#define FALSE 0
#define MAXSIZE 50
#define MAXNUM 16777216
#include<set>
#include<string>
#include<fstream>
using namespace std;
#define ERROR_SYN -1
//#define KEY_SYN=1~6
#define FINISH_SYN 0//#
#define IDENTIFIER_SYN 10//标识符
int lineIndex=1;
int error_index=0;
string sign_type[4]={"保留字",//for if ..
"特殊符号",//+ ( / ..
"常量",//num
"标识符"//还应该细分 以及属性(address) 先不考虑
};
string error_info[4]={
"标识符不能带有符号",
"整数越界",
"标识符长度大于32",
"非法识别num"
};
list<string> type0,type1,type2,type3;
list<string>::iterator finditer;
char *object;
typedef char datatype;
typedef struct /*定义缓冲队列*/
{
datatype data[MAXSIZE*2];
int front,rear;
}Queue;
void setnull(Queue *q) /*队列初始化*/
{
q->front = MAXSIZE*2 - 1;
q->rear = MAXSIZE*2 - 1;
}
BOOL empty(Queue *q) /*判队空*/
{
if(q->front==q->rear)
return TRUE;
return FALSE;
}
BOOL full(Queue *q) /*判队满*/
{
if(q->front == (q->rear+1) % (MAXSIZE*2))
return TRUE;
return FALSE;
}
int quantity(Queue *q) /*求队列中元素个数*/
{
int n;
n = q->rear - q->front;
if(n<0)
n += MAXSIZE*2;
return n;
}
datatype front(Queue *q) /*取队头元素*/
{
int n;
if(empty(q))
return 0;
n = (q->front+1) % (MAXSIZE*2);
return q->data[n];
}
BOOL enqueue(Queue *q,datatype x) /*入队*/
{
if(full(q))
return FALSE;
q->rear = ++q->rear % (MAXSIZE*2);
q->data[q->rear]=x;
return TRUE;
}
datatype dequeue(Queue *q) /*出队*/
{
if(empty(q))
return 0;
q->front = ++q->front % (MAXSIZE*2);
return q->data[q->front];
}
int lengtharray(char *a){
return strlen(a);
}
char token[MAXSIZE];
char* rwtab[6]={"begin","if","then","while","do","end"};//定义关键字
int syn;//标识符数字
Queue prog;
BOOL letter(char &ch) /*判断是否字母*/
{
if(ch>='a'&&ch<='z' ){
return TRUE;}
else if(ch>='A'&&ch<='Z'){
ch=ch+32;
return TRUE;
}//全部转换成小写
return FALSE;
}
BOOL digit(char ch,char ch2) /*判断是否36进制开头*/
{
if(ch =='0'&& (ch2 =='X' || ch2 == 'x'))
return TRUE;
return FALSE;
}
BOOL digit1(char ch) /*判断是否10进制*/
{
if(ch >='0'&& ch<= '9')
return TRUE;
return FALSE;
}
BOOL symbol(char ch){
if((ch>=34&&ch<=36)||ch==39||ch==64||(ch>=44&&ch<46))return TRUE;
else return FALSE;
}
BOOL isPoint(char ch){
if(ch==46)return true;
else return false;
}
BOOL isBottomLine(char ch){
if(ch==95)return true;
else return false;
}
//判断整数字符
BOOL digitagain(char ch){
if ((ch >= '0' && ch <= '9')||(ch>='a'&&ch<='z' ) ||(ch>='A'&&ch<='Z'))return TRUE;
return FALSE;
}
int translate(char c){
int p;
if(c>='0'&&c<='9')p=c-'0';
if(c>='a'&&c<='z')p=c-'a'+10;
if(c>='A'&&c<='Z')p=c-'A'+10;
return p ;
}
BOOL explain(char ch,char ch2){
if(ch == '-' && ch2 == '-')
return TRUE;
return FALSE;
}
void scanner() /*扫描器*/
{
int i;
int num,num1;
char ch;
char ch2;
for(i=0;i<50;i++){
token[i]=0;}
i=0;
do /*去除多余空格、换行及制表符*/
{
ch=dequeue(&prog);
if(ch=='
'){
lineIndex++;
}
}while(ch==' ' || ch=='
' || ch==' ');//读到不是空格、换行及制表符
ch2 = prog.data[prog.front+1];
if(letter(ch)) /*识别标识符(编号10)*/
{
int flag = 0;//
while(1)
{
token[i++]=ch;
ch=front(&prog);
if(letter(ch) || digitagain(ch)||isBottomLine(ch))
dequeue(&prog);
else if(symbol(ch)||isPoint(ch)){
dequeue(&prog);
flag=1;//非法变量
}
else break;
}
if(flag!=0)
{
syn=ERROR_SYN;error_index=0; return;
}
//标识符长度大于32报错
if(lengtharray(token)>32){syn=ERROR_SYN;error_index=2; return;}
//标识符的有效长度为8
if(lengtharray(token)>7)token[8]=' ';
token[i]=' ';
syn=10;
for(i=0;i<6;i++)
if(!strcmp(token,rwtab[i]))
syn=i+1; /*识别关键字(编号1到6)*/
}
else if(explain(ch,ch2)){ /*识别注释*/
prog.front=prog.front+1; //移动到--后面
while(1){
ch = front(&prog);
if(ch!='
')dequeue(&prog);
else {syn=-2;break;}
}
}
else if(digit(ch,ch2)) /*识别无符号整数(编号11)*/
{
prog.front=prog.front+1; //移动到0X后面
int flag=0;
while(1)
{
ch=front(&prog);
if(digitagain(ch)){
dequeue(&prog);
}
else{
break;
}
token[i++]=ch;
}
//转换成36进制数
int j,k;
k=0;num=0;
for(j = i-1;j>=0;j--){
num+=translate(token[j])*(int)pow(36,k);
// printf("%d
" ,translate(token[j]));
k++;
}
if (num > MAXNUM){
token[0]=' ';
syn=ERROR_SYN;error_index=1;
// printf("error
");
//break;
}
else{
//将十进制数输入到文本
int num_1;
num_1 = num;
int q;
for (q=1;;q++){
num/=10;
if (num==0) break;
}
int w,e;
e=q-1;
for (w=0;w<q;w++){
token[w] = (num_1/((int)pow(10,e))) +48;
num_1 %= ((int)pow(10,e));
e--;
}
token[e]=' ';
syn=11;
}
}
else if(digit1(ch)){
int flag = 0;
int k=0;
BOOL havaPoint = FALSE;
while(1)
{
token[i++]=ch;
ch=front(&prog);
if(digit1(ch))
{
k++;
dequeue(&prog);
//nothing
}
else if(symbol(ch)||letter(ch)||isBottomLine(ch)){
dequeue(&prog);
flag=1;//非法变量
}
else if(isPoint(ch)){
dequeue(&prog);
havaPoint=TRUE;
break;
}
else break;
}
if(havaPoint==TRUE){
while(1)
{
token[i++]=ch;
ch=front(&prog);
if(digit1(ch))
{
dequeue(&prog);
//nothing
}
else if(symbol(ch)||letter(ch)||isBottomLine(ch)||isPoint(ch)){
dequeue(&prog);
flag=1;//非法变量
}
else break;
}
if(flag==0)flag=2;
}
if(flag==1){
syn=ERROR_SYN;error_index=3; return;
}
token[i]=' ';
//转换成10进制数
int j;
num1=0;
k--;
for(j = 0;j<=i-1;j++){
if(isPoint(token[j])){break;}
num1+=translate(token[j])*(int)pow(10,k);
k--;
if (num1 > MAXNUM){
token[0]=' ';
syn=ERROR_SYN;error_index=1;
return;
}
}
if(flag==2)syn=12;
syn=11;
}
else
switch(ch)
{
case '#': /*识别结束符‘#’(编号0)*/
syn=0;
token[i++]='#';
token[i]=' ';
break;
case '+': /*识别‘+’(编号13)*/
syn=13;
token[i++]='+';
token[i]=' ';
break;
case '-': /*识别‘-’(编号14)*/
syn=14;
token[i++]='-';
token[i]=' ';
break;
case '*': /*识别‘*’(编号15)*/
syn=15;
token[i++]='*';
token[i]=' ';
break;
case '/': /*识别‘/’(编号16)*/
syn=16;
token[i++]='/';
token[i]=' ';
break;
case ':':
token[i++]=':';
ch=front(&prog);
switch(ch)
{
case '=': /*识别‘:=’(编号18)*/
syn=18;
token[i++]='=';
token[i]=' ';
dequeue(&prog);
break;
default: /*识别‘:’(编号17)*/
syn=17;
token[i]=' ';
break;
}
break;
case '<':
token[i++]='<';
ch=front(&prog);
switch(ch)
{
case '>': /*识别‘<>’(编号21)*/
syn=21;
token[i++]='>';
token[i]=' ';
dequeue(&prog);
break;
case '=': /*识别‘<=’(编号22)*/
syn=22;
token[i++]='=';
token[i]=' ';
dequeue(&prog);
break;
default: /*识别‘<’(编号20)*/
syn=20;
token[i]=' ';
break;
}
break;
case '>':
token[i++]='>';
ch=front(&prog);
switch(ch)
{
case '=': /*识别‘>=’(编号24)*/
syn=24;
token[i++]='=';
token[i]=' ';
dequeue(&prog);
break;
default: /*识别‘>’(编号23)*/
syn=23;
token[i]=' ';
break;
}
break;
case '=': /*识别‘=’(编号25)*/
syn=25;
token[i++]='=';
token[i]=' ';
break;
case ';': /*识别‘;’(编号26)*/
syn=26;
token[i++]=';';
token[i]=' ';
break;
case '(': /*识别‘(’(编号27)*/
syn=27;
token[i++]='(';
token[i]=' ';
break;
case ')': /*识别‘)’(编号28)*/
syn=28;
token[i++]=')';
token[i]=' ';
break;
default: /*出错!*/
syn=-1;
break;
}
}
int main()
{
FILE *in,*out;
ofstream outfile;
ofstream inputfile;
set<string> mset;
int i;
string ms;
char ch;
setnull(&prog); /*缓冲队列初始化*/
printf("在input.txt里面输入内容(结束符为#),out.txt中查看输出
");
char *argv[]={"E:/ofname.txt","input.txt","out.txt"};
//w+ 存在则清空内容,否则新建文件
if(!(in=fopen(argv[1],"r+")))
{
printf("请在input.txt中输入内容!(结束符为#)
");
in=fopen(argv[1],"w+");
fputc('#',in);
fclose(in);
return 0;
}
out=fopen(argv[2],"w+");
outfile.open(argv[2],ios::in);
do
{
do
{
ch=fgetc(in);
enqueue(&prog,ch);
}while(ch!='#' && !full(&prog));
if(ch=='#')
fclose(in);
do
{
scanner();
switch(syn)
{
case -2:
break;
case 0:
break;
case -1:
outfile <<">>>> error:在第"<<lineIndex<<"行,原因:"<<error_info[error_index]<<endl;
break;
default:
outfile <<">>>> ";
i=0;
ms="";
do
{
ms+=token[i];
outfile<<token[i++];
// fputc(token[i++],out);
}while(token[i]!=' ');
if(syn==10){
outfile<<" "<<sign_type[3];
finditer=find(type3.begin(),type3.end(),ms);
if(finditer==type3.end())
type3.push_back(ms);//没找到就插入
}
else if(syn==11||syn==12){
outfile<<" "<<sign_type[2];
finditer=find(type2.begin(),type2.end(),ms);
if(finditer==type2.end())
type2.push_back(ms);//没找到就插入
}
else if(syn>=13&&syn<=28){
outfile<<" "<<sign_type[1];
finditer=find(type1.begin(),type1.end(),ms);
if(finditer==type1.end())
type1.push_back(ms);//没找到就插入
}
else if(syn>=1&&syn<=6){
outfile<<" "<<sign_type[0];
finditer=find(type0.begin(),type0.end(),ms);
if(finditer==type0.end())
type0.push_back(ms);//没找到就插入
}
outfile<<endl;
//fputc(',',out);
// i=syn/10;
//if(i!=0)outfile<<i+48;
//outfile<<syn%10+48<<endl;
//fputc(syn%10+48,out);
//fputc('
',out);
break;
}
}while(syn!=0 && (quantity(&prog) > MAXSIZE || ch=='#'));//以警号作为程序结束标志
}while(ch!='#');
outfile <<endl<<"符号表:"<<endl;
list<string>::iterator eachit;
outfile << sign_type[0] <<endl;
for(eachit=type0.begin();eachit!=type0.end();++eachit){
outfile << *eachit <<endl;
}
outfile << sign_type[1] <<endl;
for(eachit=type1.begin();eachit!=type1.end();++eachit){
outfile << *eachit <<endl;
}
/*
outfile << sign_type[2] <<endl;
for(eachit=type2.begin();eachit!=type2.end();++eachit){
outfile << *eachit <<endl;
}
*/
outfile << sign_type[3] <<endl;
for(eachit=type3.begin();eachit!=type3.end();++eachit){
outfile << *eachit <<endl;
}
outfile.close();
return 0;
}
语法分析 slr(1) _by MichaelZ
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<list>
using namespace std;
char KeyWords[10][10] = { "do", "else", "if", "return", "void", "while","program","begin","end","then"};
int slr1[102][26];// 分析表 赋值(s9=900,r1=1;acc=30)
char creat[23][15]={"0","A->pi(H);C.","H->i","H->H,i","C->bOe","O->S","O->","S->T",
"S->S;T","T->i:E","T->C","T->fBtT","T->fBtTlT","T->wBdT","B->E<E","E->E+M","E->M","M->M*F","M->F","F->i","F->n"};//文法单元;
char temp[10],p,in[100],table[100][10];//存放识别字符串;
int t,j,val,b,flag;
char flag1,put[100],*arr;
int begin=0,forward=0,pos;// 开始符号和向前看指针;
FILE *out=fopen("out.txt","w");//用文件进行输出
int main()
{
//SLR(1)分析表
int slr1[45][32]={
{0, 200,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 100,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,30, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,300,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,400,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,600,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,500,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,700,0, 0,800,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,2,0, 0,2,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,900, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,1000,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,0, 0,0,1200,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,1100,0,0, 0,0,0,0,0 },
{0, 0,0,0,3,0, 0,3,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,0, 1300,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,1700,0,0,0, 0,0,1200,0,0, 1900,0,0,2000,0, 0,0,0,0,0, 0,0,1800,1400,1500, 1600,0,0,0,0 },
{0, 0,0,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,0,0,0 },
{0, 0,0,0,0,0, 0,0,0,2100,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,2200, 0,0,0,5,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,7, 0,0,0,7,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,0, 0,0,0,0,2300, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,10, 0,0,0,10,0, 0,0,10,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,2800,0,0,0, 0,0,0,2900,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,2400,2500,2600,2700 },
{0, 0,2800,0,0,0, 0,0,0,2900,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,3000,2500,2600,2700 },
{0, 0,0,0,0,4, 4,0,0,4,0, 0,0,4,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,1700,0,0,0, 0,0,1200,0,0, 1900,0,0,2000,0, 0,0,0,0,0, 0,0,1800,0,0, 3100,0,0,0,0 },
{0, 0,2800,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,2900,0, 0,0,0,0,0, 0,0,3200,2600,2700 },
{0, 0,0,0,0,0, 0,0,0,0,0, 0,3300,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 3400,3500,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,16, 0,0,0,16,0, 0,16,16,0,16, 16,16,3600,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,18, 0,0,0,18,0, 0,18,18,0,18, 18,18,18,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,19, 0,0,0,19,0, 0,19,19,0,19, 19,19,19,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,20, 0,0,0,20,0, 0,20,20,0,20, 20,20,20,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,3700, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,8, 0,0,0,8,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,9, 0,0,0,9,0, 0,0,9,0,0, 0,3500,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,1700,0,0,0, 0,0,1200,0,0, 1900,0,0,2000,0, 0,0,0,0,0, 0,0,1800,0,0, 3800,0,0,0,0 },
{0, 0,2800,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,2900,0, 0,0,0,0,0, 0,0,3900,2600,2700 },
{0, 0,2800,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,2900,0, 0,0,0,0,0, 0,0,0,4000,2700 },
{0, 0,2800,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,2900,0, 0,0,0,0,0, 0,0,0,0,4000,2700 },
{0, 0,1700,0,0,0, 0,0,1200,0,0, 1900,0,0,2000,0, 0,0,0,0,0, 0,0,1800,0,0, 4200,0,0,0,0 },
{0, 0,0,0,0,11, 0,0,0,11,0, 0,0,4300,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,0, 0,0,0,0,0, 0,14,0,0,14, 0,3500,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,15, 0,0,0,15,0, 0,15,15,0,15, 15,15,3600,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,17, 0,0,0,17,0, 0,17,17,0,17, 17,17,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,0,0,0,13, 0,0,0,13,0, 0,0,13,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 },
{0, 0,1700,0,0,0, 0,0,1200,0,0, 1900,0,0,2000,0, 0,0,0,0,0, 0,0,1800,0,0, 4400,0,0,0,0 },
{0, 0,0,0,0,12, 0,0,0,12,0, 0,0,12,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0 }
};
list<int> list1;//链表定义
list<char> list2;
list<int>::iterator it1;//itrator做指针
list<char>::iterator it2;
//读取文件以达到输入的目的
void print(int flag);//print函数用于输入字符的类别判断与输出,并且将得到的类型存入in[]中
//in[]作为简化后的输入串
int group(char flag1 );//group函数用于确定项在分析表中的列号数
int size,i=0,l=1;
char ch;
FILE *fp=fopen("file.txt","r");//用文件进行输入
if (out==NULL){ return 0;}
if (fp==NULL){ return 0;}
fseek(fp,0,2);//找到文件尾
size=ftell(fp); //ftell存入的是偏移地址
arr=new char[size];
if ((fp=fopen("file.txt","r"))==NULL) exit(1);
if ((out=fopen("out.txt","w"))==NULL) exit(1);
while (!feof(fp))
{
ch=fgetc(fp);
arr[i++]=ch;//array用于存储文件中的字符
}
fclose(fp);
size=i-1;
int state;//状态;
i=0;
//词法分析器
while(i<=size)
{
for(t=0;t<8;t++)
temp[t]=0;
if(begin==forward)
{
ch=arr[forward];
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z') state=9;
else if(ch>='0'&&ch<='9')state=12;
else if(ch=='+'||ch=='-'||ch=='*'||ch=='/')state=25;
else if(ch=='<'||ch=='>'||ch==':')state=0;
else if(ch=='.'||ch==','||ch==';'||ch=='('||ch==')')state=30;
else if (ch=='
'||ch==' '||ch==' ') state=22;
else state=31;
}
switch(state)
{
case 0: {ch=arr[i++];forward++;}
if(ch=='<')state=1;
else if(ch=='='){state=5;}
else if(ch=='>')state=6;
break;
case 1:{ch=arr[i++];forward++;}
if(ch=='=')state=2;
else if(ch=='>')state=3;
else state=4;
break;
case 2:print(5); break;
case 3:print(5); break;
case 4:{i=i-1;forward=forward-1;print(5);}
break;
case 5:print(5);break;
case 6:{ch=arr[i++];forward++;}
if(ch=='=')state=7;
else state=8;
break;
case 7:print(5);break;
case 8:{i=i-1;forward=forward-1;print(5);}
break;
case 9:{ch=arr[i++];forward++;}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))state=10;
break;
case 10:{ch=arr[i++];forward++;}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))state=10;
else if(ch>='0'&&ch<='9')state=10;
else state=11;
break;
case 11:
i=i-1;forward=forward-1;print(1);
break;
case 12:{ch=arr[i++];forward++;}
if(ch>='0'&&ch<='9')state=13;
break;
case 13:{ch=arr[i++];forward++;}
if(ch>='0'&&ch<='9')state=13;
else if (ch=='E')state=16;
else if(ch=='.')state=14;
else state=20;
break;
case 14:{ch=arr[i++];forward++;}
if(ch>='0'&&ch<='9')state=15;
else state=32;
break;
case 15:{ch=arr[i++];forward++;}
if(ch>='0'&&ch<='9')state=15;
else if(ch=='E')state=16;
else state=21;
break;
case 16:{ch=arr[i++];forward++;}
if(ch>='0'&&ch<='9')state=18;
else if(ch=='+'||ch=='-')state=17;
else state=32;
break;
case 17:{ch=arr[i++];forward++;}
if(ch>='0'&&ch<='9')state=18;
else state=32;
break;
case 18:{ch=arr[i++];forward++;}
if(ch>='0'&&ch<='9')state=18;
else state=19;
break;
case 19:{i=i-1;forward=forward-1;print(2);}break;
case 20:{i=i-1;forward=forward-1;print(2);}break;
case 21:{i=i-1;forward=forward-1;print(2);}break;
case 22:{ch=arr[i++];forward++;}
if(ch=='
'||ch==' '||ch==' ')
state=23;
break;
case 23:{ch=arr[i++];forward++;}
if(ch=='
'||ch==' '||ch==' ') state=23;
else state=24;
break;
case 24:{i=i-1; forward=forward-1;begin+=1; forward=begin;}
break;
case 25:{ch=arr[i++];forward++;}
if(ch=='+')state=26;
else if(ch=='-')state=27;
else if(ch=='*')state=28;
else if(ch=='/')state=29;
break;
case 26:print(4);break;
case 27:print(4);break;
case 28:print(4);break;
case 29:print(4);break;
case 30:{ch=arr[i++];forward++;}print(3);break;
case 31:{ch=arr[i++];forward++;}print(6);break;
case 32:{i=i-1;forward=forward-1;}print(6);break;
}
}
//语法分析;字符串输入以$结束
printf("输入的字符串以结束$
");
fputs("输入的字符串以结束$
",out);
in[val]='$';
printf("%s",in);
printf("
");
fputs(in,out);
fputs("
",out);
i=0;j=0;
list1.push_back(0);//push_back() //增加一元素到链表尾
char n,c;
int m,st,len;
printf("栈 符号 输入 动作
");
fputs("栈 符号 输入 动作
",out);
while(1)
{
char s[10];
char b[1000]={0};
//begin() 返回第一个元素的指针(iterator)
//返回最后一个元素的下一位置的指针(list为空时end()=begin())
for(it1=list1.begin();it1!=list1.end();it1++){
//printf("%d",*it1);
//整形字符串拼接
sprintf(s, "%d",*it1);
sprintf(b,"%s%s",b,s);
}
//printf("%s",b);
fputs(b,out);
// printf(" ");
fputs(" ",out);
for(it2=list2.begin();it2!=list2.end();it2++){
// printf("%c",*it2);
fputc(*it2,out);
}
// printf(" ");
fputs(" ",out);
for(i=j;i<=val;i++){
printf("%c",in[i]);
fputc(in[i],out);
}
//printf(" ");
fputs(" ",out);
st=list1.back();
n=in[j];
flag=group(n);//得到当前状态行数
if(slr1[st][flag]>100)
{
m=slr1[st][flag]/100;
printf("移入
");
fputs("移入
",out);
list1.push_back(m);
list2.push_back(in[j]);
j++;
}
else if(slr1[st][flag]<100&&slr1[st][flag]!=30&&slr1[st][flag]!=0)
{
m=slr1[st][flag];
printf("根据%s规约
",creat[m]);
fputs("根据",out);
fputs(creat[m],out);
fputs("规约
",out);
c=creat[m][0];
flag=group(c);
len=strlen(creat[m])-3;
for(i=0;i<len;i++)
{ list1.pop_back();
list2.pop_back();
}
st=list1.back();
//printf("
%d
",st);
//printf("
%d
",flag);
list2.push_back(c);
m=slr1[st][flag]/100;
list1.push_back(m);
}
else if(slr1[st][flag]==30)
{
printf("接受
");
fputs("接受
",out);
break;
}
else if(slr1[st][flag]==0)
{
printf("
");
fputs("
",out);
printf("%s",table[j-1]);
fputs(table[j-1],out);
printf("%s ",table[j]);
fputs(table[j],out);
printf("ERROR
");
fputs("ERROR
",out);
break;
}
}
fclose(out);
return 0;
}
void print(int b) //输出
{
pos=begin;
for(t=0;t<forward-begin;t++)
{
p=arr[pos++];temp[t]=p;
}
begin=forward;
switch(b)
{
case 1:
{
for(j=0; j<55; j++)
if(strcmp(temp,KeyWords[j])==0)
{
printf("<%s keyword>
",temp);
fputs("<",out);
fputs(temp,out);
fputs(" keyword>
",out);
if(strcmp(temp,"if")==0)
{
strcpy(table[val],temp);
in[val++]='f'; break;}
else if(strcmp(temp,"program")==0)
{
strcpy(table[val],temp);
in[val++]='p'; break;}
else if(strcmp(temp,"end")==0)
{
strcpy(table[val],temp);
in[val++]='e'; break;}
else if(strcmp(temp,"else")==0)
{
strcpy(table[val],temp);
in[val++]='l'; break;}
else if(strcmp(temp,"while")==0)
{
strcpy(table[val],temp);
in[val++]='w'; break;}
else if(strcmp(temp,"do")==0)
{
strcpy(table[val],temp);
in[val++]='d'; break;}
else if(strcmp(temp,"then")==0)
{
strcpy(table[val],temp);
in[val++]='t'; break;}
else
{
strcpy(table[val],temp);
in[val++]='b'; break; }
}
if(j==55)
{ printf("<%s id>
",temp);
fputs("<",out);
fputs(temp,out);
fputs(" id>
",out);
strcpy(table[val],temp);
in[val++]='i';}
}break;
case 2:
printf("<%s num>
",temp);
fputs("<",out);
fputs(temp,out);
fputs(" num>
",out);
strcpy(table[val],temp);
in[val++]='n';
break;
case 3:
printf("<%s division>
",temp);
fputs("<",out);
fputs(temp,out);
fputs(" division>
",out);
strcpy(table[val],temp);
in[val++]=temp[0];
break;
case 4:
printf("<%s relation>
",temp);
fputs("<",out);
fputs(temp,out);
fputs(" relation>
",out);
strcpy(table[val],temp);
in[val++]=temp[0];
break;
case 5:
printf("<%s operator>
",temp);
fputs("<",out);
fputs(temp,out);
fputs(" operator>
",out);
strcpy(table[val],temp);
in[val++]=temp[0];
break;
case 6:
printf("<%s ERROR>
",temp);
fputs("<",out);
fputs(temp,out);
fputs(" ERROR>
",out);
break;
}
}
int group(char flag1 )
{
if(flag1=='p')
flag=1;
else if(flag1=='i')
flag=2;
else if(flag1=='(')
flag=3;
else if(flag1==')')
flag=4;
else if(flag1==';')
flag=5;
else if(flag1=='.')
flag=6;
else if(flag1==',')
flag=7;
else if(flag1=='b')
flag=8;
else if(flag1=='e')
flag=9;
else if(flag1==':')
flag=10;
else if(flag1=='f')
flag=11;
else if(flag1=='t')
flag=12;
else if(flag1=='l')
flag=13;
else if(flag1=='w')
flag=14;
else if(flag1=='d')
flag=15;
else if(flag1=='<')
flag=16;
else if(flag1=='+')
flag=17;
else if(flag1=='*')
flag=18;
else if(flag1=='n')
flag=19;
else if(flag1=='$')
flag=20;
else if(flag1=='A')
flag=21;
else if(flag1=='H')
flag=22;
else if(flag1=='C')
flag=23;
else if(flag1=='O')
flag=24;
else if(flag1=='S')
flag=25;
else if(flag1=='T')
flag=26;
else if(flag1=='B')
flag=27;
else if(flag1=='E')
flag=28;
else if(flag1=='M')
flag=29;
else if(flag1=='F')
flag=30;
return(flag);
}
语义分析 by france&lola
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cstring>
using namespace std;
//词法分析双向链表(存已识别的词单元(endSign))
typedef struct WordAnalysisList
{
struct WordAnalysisList *last;
char index;//以字母作为标号 其index为在endSign中对应的元素
char value[128];//对应值字符串
struct WordAnalysisList *next;
}WordAnalysisList;
//headWAL 对应语法分析时的输入
WordAnalysisList *headWAL, *currendWAL;
//headSignStack:符号栈 从null到最后被规约成S tail4:反着显示要用到
WordAnalysisList *headSignStack, *tail4;
typedef struct Tree
{
int number;
char bb[128];
struct Tree *haveF;
struct Tree *child[4];
}Tree;
Tree *root;
//语法分析栈
typedef struct stack
{
struct stack *last;
//当前栈的值(规约规则的序号)
int number;
//非终结符的个数
int flag;
char bb[128];
struct Tree *haveF;
struct stack *next;
}Stack;
Stack *stackHead, *tail2;
//存规约顺序
Stack *guiYueOrderheadTemp;
//在guiYueOrderheadTemp初始化的时候赋值给guiYueOrderhead 存的是第一个规约
Stack *guiYueOrderhead;
//对语法树进行前序遍历
Stack * grammarTreePreorderHead;
//用来存储 id或者number
typedef struct Str2
{
char sstr[128];
struct Str2 *next;
}Str2;
//head*:规约时将识别到的id或num放入list
Str2 *headid, *headnum, *headid2, *headnum2;
int id = 0, num = 0, ok = 1;
char str[128], Bool[128];
//初始化词法分析
void initMorphology(){
headWAL = NULL;
currendWAL = NULL;
}
//行号
int line = 1;
//act[i][j]=a:第i个状态在第j个终结符执行的操作:a>0表示sa,a<0表示ra a=0表示acc
int act[45][20];
//gt[i][j]=b:规约pop stack后第i个状态在第j个终结符时跳转到第b个状态
int gt[45][10];
//haveF[i][j] = c第i个字母在第j个产生式中存在c次
int haveF[10][21];
//全局的Lx Tx;
int L = 0, T = 0;
//具体的产生式规则
char gg[21][128] = { "s'->A", "S -> program id ( id_lists ); compound_stmt .", "id_lists -> id ", "id_lists -> id_lists , id ", "compound_stmt -> begin optional_stmts end", "optional_stmts -> stmts ", "optional_stmts -> ε", "stmts -> stmt ", "stmts -> stmts; stmt ", "stmt -> id := expr ", "stmt -> compound_stmt", "stmt -> if bool then stmt ", "stmt -> if bool then stmt else stmt ", "stmt -> while bool do stmt", "bool -> expr < expr ", "expr -> expr + term ", "expr -> term", "term -> term * factor ", "term -> factor", "factor -> id ", "factor -> num" };
//简化的产生式规则
char g[21][12] = { "s'->A", "A->bcdBefCg", "B->c", "B->Bhc", "C->iDj", "D->E", "D->ε", "E->F", "E->EfF", "F->ckH", "F->C", "F->lGmF", "F->lGmFnF", "F->oGpF", "G->HqH", "H->HrI", "H->I", "I->IsJ", "I->J", "J->c", "J->t" };
//规约时栈pop的个数
int Number[21] = { 1, 8, 1, 3, 3, 1, 0, 1, 3, 3, 1, 4, 6, 4, 3, 3, 1, 3, 1, 1, 1 };
//非终结符
char noend[10][15] = { "S", "id_lists", "compound_stmt", "optional_stmts", "stmts", "stmt", "bool", "expr", "term", "factor" };
//终结符
char endSign[21][8] = { "ε", "program", "id", "(", ")", ";", ".", ",", "begin", "end", ":=", "if", "then", "else", "while", "do", "<", "+", "*", "num", "$" };
/*
初始化语法分析表(手动)
act[i][j]=a:第i个状态在第j个终结符执行的操作:a>0表示sa,a<0表示ra a=0表示acc
gt[i][j]=b:规约pop stack后第i个状态在第j个终结符时跳转到第b个状态
haveF[i][j] = c第i个字母在第j个产生式中存在c次
*/
void initGrammar()
{
act[0][0] = 2;
act[1][19] = 0;
act[2][1] = 3;
act[3][2] = 4;
act[4][1] = 6;
act[5][3] = 7; act[5][6] = 8;
act[6][3] = -2; act[6][6] = -2;
act[7][4] = 9;
act[8][1] = 10;
act[9][7] = 12;
act[10][3] = -3; act[10][6] = -3;
act[11][5] = 13;
act[12][1] = 17; act[12][7] = 12; act[12][8] = -6; act[12][10] = 19; act[12][13] = 20;
act[13][19] = -1;
act[14][8] = 21;
act[15][4] = 22; act[15][8] = -5;
act[16][4] = -7; act[16][8] = -7;
act[17][9] = 23;
act[18][4] = -10; act[18][8] = -10; act[18][12] = -10;
act[19][1] = 28; act[19][18] = 29;
act[20][1] = 28; act[20][18] = 29;
act[21][4] = -4; act[21][5] = -4; act[21][8] = -4; act[21][12] = -4;
act[22][1] = 17; act[22][7] = 12; act[22][10] = 19; act[22][13] = 20;
act[23][1] = 28; act[23][18] = 29;
act[24][11] = 33;
act[25][15] = 34; act[25][16] = 35;
act[26][4] = -16; act[26][8] = -16; act[26][11] = -16; act[26][12] = -16; act[26][14] = -16; act[26][15] = -16; act[26][16] = -16; act[26][17] = 36;
act[27][4] = -18; act[27][8] = -18; act[27][11] = -18; act[27][12] = -18; act[27][14] = -18; act[27][15] = -18; act[27][16] = -18; act[27][17] = -18;
act[28][4] = -19; act[28][8] = -19; act[28][11] = -19; act[28][12] = -19; act[28][14] = -19; act[28][15] = -19; act[28][16] = -19; act[28][17] = -19;
act[29][4] = -20; act[29][8] = -20; act[29][11] = -20; act[29][12] = -20; act[29][14] = -20; act[29][15] = -20; act[29][16] = -20; act[29][17] = -20;
act[30][14] = 37;
act[31][4] = -8; act[31][8] = -8;
act[32][4] = -9; act[32][8] = -9; act[32][12] = -9; act[32][16] = 35;
act[33][1] = 17; act[33][7] = 12; act[33][10] = 19; act[33][13] = 20;
act[34][1] = 28; act[34][18] = 29;
act[35][1] = 28; act[35][18] = 29;
act[36][1] = 28; act[36][18] = 29;
act[37][1] = 17; act[37][7] = 12; act[37][10] = 19; act[37][13] = 20;
act[38][4] = -11; act[38][8] = -11; act[38][12] = 43;
act[39][11] = -14; act[39][14] = -14; act[39][16] = 35;
act[40][4] = -15; act[40][8] = -15; act[40][11] = -15; act[40][12] = -15; act[40][14] = -15; act[40][15] = -15; act[40][16] = -15; act[40][17] = 36;
act[41][4] = -17; act[41][8] = -17; act[41][11] = -17; act[41][12] = -17; act[41][14] = -17; act[41][15] = -17; act[41][16] = -17; act[41][17] = -17;
act[42][4] = -13; act[42][8] = -13; act[42][12] = -13;
act[43][1] = 17; act[43][7] = 12; act[43][10] = 19; act[43][13] = 20;
act[44][4] = -12; act[44][8] = -12; act[44][12] = -12;
gt[0][0] = 1;
gt[4][1] = 5;
gt[9][2] = 11;
gt[12][2] = 18; gt[12][3] = 14; gt[12][4] = 15; gt[12][5] = 16;
gt[19][6] = 24; gt[19][7] = 25; gt[19][8] = 26; gt[19][9] = 27;
gt[20][6] = 30; gt[20][7] = 25; gt[20][8] = 26; gt[20][9] = 27;
gt[22][2] = 18; gt[22][5] = 31;
gt[23][7] = 32; gt[23][8] = 26; gt[23][9] = 27;
gt[33][2] = 18; gt[33][5] = 38;
gt[34][7] = 39; gt[34][8] = 26; gt[34][9] = 27;
gt[35][8] = 40; gt[35][9] = 27;
gt[36][9] = 41;
gt[37][2] = 18; gt[37][5] = 42;
gt[43][2] = 18; gt[43][5] = 44;
haveF[1][1] = 1; haveF[1][3] = 1;
haveF[2][1] = 1; haveF[2][10] = 1;
haveF[3][4] = 1;
haveF[4][5] = 1; haveF[4][8] = 1;
haveF[5][7] = 1; haveF[5][8] = 1; haveF[5][11] = 1; haveF[5][12] = 2; haveF[5][13] = 1;
haveF[6][11] = 1; haveF[6][12] = 1; haveF[6][13] = 1;
haveF[7][9] = 1; haveF[7][14] = 2; haveF[7][15] = 1;
haveF[8][15] = 1; haveF[8][16] = 1; haveF[8][17] = 1;
haveF[9][17] = 1; haveF[9][18] = 1;
}
/*
增加词法节点
以标号c和值s[]建一个节点,并加到词法分析链表的最后面
*/
void addWordNode(char c, char s[])
{
WordAnalysisList *temp;
//创建WAL_Node
temp = (WordAnalysisList*)malloc(sizeof(WordAnalysisList));
temp->index = c;
if (s)
strcpy(temp->value, s);
if (headWAL == NULL)
{
headWAL = temp;
currendWAL = headWAL;
}
else
{
printf("currend value:%s
", currendWAL->value);
if (headWAL->next == NULL){
headWAL->next = temp;
currendWAL = headWAL->next;
}
else{
currendWAL->next = temp;
currendWAL = currendWAL->next;
}
currendWAL->next = NULL;
}
}
/*
识别关键字
传入文件开始识别指针
返回关键字所在endSign数组中的位置 或 报error返回
*/
void keyword(FILE *fp)
{
char ch, instring[128];
int n = 0;
do{
ch = fgetc(fp);
instring[n++] = ch;
} while ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'));
fseek(fp, -1L, 1);
instring[--n] = 0;
_strlwr(instring);//将字符串中的字符转换为小写
int i;
for (i = 1; i<20; i++)
{
if (i != 2 && i != 19)
{
if (strcmp(instring, endSign[i]) == 0)
break;
}
}
if (i<20)
{
//加入关键字
addWordNode(97 + i, instring);
}
else
{
if (n>32)
printf("-->>error标识符过长! line:%d
", line);
//加入id
addWordNode(97 + 2, instring);
}
}
void number(FILE *fp, int flag)
{
char ch, instring[128];//,instring2[128];
int n = 0; int number = 0; int m;
do{
ch = fgetc(fp);
instring[n++] = ch;
} while (ch >= '0'&&ch <= '9');
fseek(fp, -1L, 1);
instring[--n] = ' ';
for (int i = 0; i<n; i++)
{
m = 1;
for (int j = 0; j<(n - i - 1); j++)
m *= 10;
number += (instring[i] - 48)*m;
}
//加入number
addWordNode(97 + 19, instring);
}
void number36(FILE *fp)
{
char ch, instring[128];
int n = 0;
int number = 0, m;
do{
ch = fgetc(fp);
if (ch == '
')
line++;
instring[n++] = ch;
} while ((ch >= '0'&&ch <= '9') || (ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'));
fseek(fp, -1L, 1);
instring[--n] = ' ';
for (int i = 0; i<n; i++)
{
m = 1;
for (int j = 0; j<(n - i - 1); j++)
m *= 36;
if (instring[i] >= '0'&&instring[i] <= '9')
number += (instring[i] - 48)*m;
else if (instring[i] >= 'a'&&instring[i] <= 'z')
number += (instring[i] - 87)*m;
else
number += (instring[i] - 55)*m;
}
if (number >= 16777216)
printf("-->> 7、error越界错误! line:%d
", line);
//加入number
addWordNode(97 + 19, instring);
}
void other(FILE *fp)
{
int endIndex = 0;
char ch = fgetc(fp);
if (ch == ' ' || ch == '
' || ch == ' ')
endIndex = -2;
char s[3];
s[0] = ch;
if (ch == ':')
{
ch = fgetc(fp);
if (ch == '=')
{
s[1] = ch; s[2] = ' ';
}
else
{
endIndex = -1;
}
}
else
{
s[1] = ' ';
}
int i;
for (i = 1; i<20; i++)
{
if (i != 2 && i != 19)
{
if (strcmp(endSign[i], s) == 0)
{
break;
}
}
}
if (i<20)
{
endIndex = i;
}
else
{
endIndex = -1;
}
if (endIndex>-1)
{
addWordNode(97 + endIndex, endSign[endIndex]);
}
}
//在词法最后增加一个表示识别结束的$符号
void addWordNodeEnd()
{
WordAnalysisList *endNode;
endNode = (WordAnalysisList*)malloc(sizeof(WordAnalysisList));
endNode->index = '$';
endNode->next = NULL;
currendWAL->next = endNode;
}
//添加当前要移入的词法单元到符号栈
void addCurrentInputWord(char c, char s[])
{
WordAnalysisList *p1;
p1 = (WordAnalysisList*)malloc(sizeof(WordAnalysisList));
p1->index = c;
if (s)
strcpy(p1->value, s);
p1->next = headSignStack;
p1->last = NULL;
headSignStack->last = p1;
headSignStack = p1;
}
//传入的s为类型number或者id的值 c=1 表示传入的是id 0 number
void addheadstr(int c, char s[])
{
printf("
addheadstr s:%s
", s);
Str2 *p1, *p2, *p3 = NULL;
p1 = (Str2*)malloc(sizeof(Str2));
strcpy(p1->sstr, s);
p1->next = NULL;
if (c == 1)
{
p2 = headid;
if (p2 == NULL)
{
headid = p1;
}
else
{
while (p2)
{
p3 = p2;
p2 = p2->next;
}
p3->next = p1;
}
}
else
{
p2 = headnum;
if (p2 == NULL)
{
headnum = p1;
}
else
{
while (p2)
{
p3 = p2;
p2 = p2->next;
}
p3->next = p1;
}
}
}
//移入或规约时产生的push
void addstack(int t)
{
Stack *p1;
p1 = (Stack*)malloc(sizeof(Stack));
p1->number = t;
p1->next = stackHead;
p1->last = NULL;
stackHead->last = p1;
stackHead = p1;
}
//存语法分析的规约顺序(t为第几条规约规则)
void addGuiyueOrder(int t)
{
Stack *p1;
p1 = (Stack*)malloc(sizeof(Stack));
p1->number = t;
p1->flag = 0;
p1->next = guiYueOrderheadTemp;
p1->last = NULL;
if (guiYueOrderheadTemp == NULL)
guiYueOrderheadTemp = guiYueOrderhead = p1;
else guiYueOrderheadTemp->last = p1;
guiYueOrderheadTemp = p1;
}
//规约时状态栈产生的pop
void popstack(int i)
{
int j = Number[i];
while (j--)
{
stackHead = stackHead->next;
}
stackHead->last = NULL;
}
//规约时符号栈产生的pop
void popSignStack(int i)
{
WordAnalysisList *p1;
p1 = headSignStack;
int j = Number[i];
while (j--)
{
p1 = p1->next;
}
if (p1)
{
p1->last = NULL;
}
headSignStack = p1;
}
//将原来缩略的产生字母转为对应的词法单元
void Printf(char aa)
{
if (aa>'a' && aa <= 'z')
{
printf("%s ", endSign[aa - 97]);
}
else if (aa >= 'A' && aa <= 'Z')
{
printf("%s ", noend[aa - 65]);
}
else if (aa == '$')
{
printf("$");
}
}
void output(int t, int j)
{
Stack *p1;
WordAnalysisList *p2, *p3, *p4;
p2 = headWAL;
p1 = tail2;
p3 = headSignStack;
p4 = tail4;
if (t != 3)
{
if (t == 1)
printf("移入
");
else if (t == 2) printf("归约%s
", gg[j]);
while (p1)
{
printf("%d ", p1->number);
p1 = p1->last;
}
printf(" ");
while (p4)
{
Printf(p4->index);
p4 = p4->last;
}
printf(" ");
while (p2)
{
Printf(p2->index);
p2 = p2->next;
}
printf(" ");
}
else printf("接受
");
}
//由词法单元去执行语法分析,得到一个规约顺序(实验二为直接输出)
void grammarAnalysis()
{
WordAnalysisList *temp;
int i, j, k;
Stack *p1;
p1 = (Stack*)malloc(sizeof(Stack));
//初始化栈
p1->number = 0;
p1->next = NULL;
p1->last = NULL;
stackHead = tail2 = p1;
WordAnalysisList *p2;
//headWAL 对应语法分析时的输入
while (1)
{
if (headWAL->index == '$')
{
j = headWAL->index - 17;
}
else
j = headWAL->index - 98;
//移入 入栈
if (act[stackHead->number][j]>0)
{
addstack(act[stackHead->number][j]);
if (tail4 == NULL)
{
//p2:当前输入的词法单元
p2 = (WordAnalysisList*)malloc(sizeof(WordAnalysisList));
p2->index = headWAL->index;
strcpy(p2->value, headWAL->value);
p2->next = NULL;
p2->last = NULL;
//加到符号栈
headSignStack = tail4 = p2;
}
else addCurrentInputWord(headWAL->index, headWAL->value);
headWAL = headWAL->next;
output(1, 0);
}
//规约 改栈
else if (act[stackHead->number][j]<0)
{
i = -act[stackHead->number][j];
//存第i条规约顺序
addGuiyueOrder(i);
//存入id或者number到2个list中
//stmt->id := expr 以前是一直移入 直到 id := expr head4为expr要找到前面的id 执行下面的操作
if (i == 9)
{
k = 2;
temp = headSignStack;
while (k--)
{
//printf("?%s
", temp->value);
temp = temp->next;
}
addheadstr(1, temp->value);
}
//factor->id 规则
else if (i == 19)
{
addheadstr(1, headSignStack->value);
}
//factor->num
else if (i == 20)
{
addheadstr(0, headSignStack->value);
}
popstack(i);
popSignStack(i);
if (headSignStack == NULL)
{
p2 = (WordAnalysisList*)malloc(sizeof(WordAnalysisList));
p2->index = g[i][0];
p2->next = NULL;
p2->last = NULL;
headSignStack = tail4 = p2;
}
else addCurrentInputWord(g[i][0], 0);
//第i条规则 左部符号在非终结符中排的位置(如B排66-65=1) 即gt中的j
addstack(gt[stackHead->number][g[i][0] - 65]);
output(2, i);
}
else if (act[stackHead->number][j] == 0)
{
if (headWAL->index != '$' || (tail4->index != 'A' || tail4->last != NULL))
{
printf("
error!
");
ok = 0;
}
else
output(3, 0);
break;
}
}
}
//规约的产生式有几个非终结符存入flag中
void noendNumToflag()
{
int t;
Stack *pp;
pp = guiYueOrderhead;
while (pp)
{
pp->haveF = NULL;
//printf("%d ",pp->number);
t = pp->number;
if (t == 2 || t == 19 || t == 20 || t == 6)
{
pp->flag = -1;//只有这句用到
}
else if (t == 3 || t == 5 || t == 7 || t == 8 || t == 9 || t == 10 || t == 16 || t == 18)
{
pp->flag = 1;
}
else if (t == 1 || t == 11 || t == 13 || t == 14 || t == 15 || t == 17)
{
pp->flag = 2;
}
else if (t == 12)
{
pp->flag = 3;
}
pp = pp->last;
}
}
//创建leaf节点(传入一条规约规则)
Tree *creatleaf(Stack *rule)
{
Tree *p1;
p1 = (Tree*)malloc(sizeof(Tree));
p1->number = rule->number;
//rule19:factor->id rule9: stmt->id := expr
if (rule->number == 19 || rule->number == 9)
{
strcpy(p1->bb, headid->sstr);
headid = headid->next;
}
//rule20:factor->num
else if (rule->number == 20)
{
strcpy(p1->bb, headnum->sstr);
headnum = headnum->next;
}
p1->haveF = NULL;
p1->child[0] = NULL;
p1->child[1] = NULL;
p1->child[2] = NULL;
p1->child[3] = NULL;
return p1;
}
Tree *creathaveF(Stack *pp, Tree *child)
{
Tree *p1;
p1 = (Tree*)malloc(sizeof(Tree));
p1->number = pp->number;
///*
if (pp->number == 19 || pp->number == 9)
{
strcpy(p1->bb, headid->sstr);
headid = headid->next;
}
else if (pp->number == 20)
{
strcpy(p1->bb, headnum->sstr);
headnum = headnum->next;
}
//*/
p1->child[0] = child;
p1->child[1] = NULL;
p1->child[2] = NULL;
p1->child[3] = NULL;
p1->haveF = NULL;
return p1;
}
//为child的添加一个产生式为p的haveF
void addhaveF(Tree *child, Stack *p)
{
int i = 0;
Tree *node;
//产生式的haveF存在 说明之前有另外一天产生式以其作为haveF了
//如A->B p:A->D C->A+A 在p找haveF时就是p->haveF =C->A+A存在
//
if (p->haveF)
{
node = p->haveF;
while (node->child[i] && i <= 3)
{
i++;
}
//寻找一个空 to添加节点
node->child[i] = child;
}
//p:A->B 的haveF没有找到 child:B->id
else
{
node = creathaveF(p, child);
p->haveF = node;
}
}
//从当前的规约顺序guiYueOrderhead开始寻找child的haveF
Stack *findhaveF(Stack *start, Tree *child)
{
Stack *p1;
p1 = start->last;
int i = 1;
int j, k;
int flag = 0;
while (p1&&flag == 0)
{
//得到当前规约规则产生式左边的标号在后面产生式右边占有j个
//实际按语法规则 出现 A->B A->B C->A+A 的顺序是对的 不会出现 A->B C->A+A A->B 的顺序
//A->B A->B A->B C->A+A D->A E->DC 那么第一条A->B的haveF为D->A (有待研究)
j = haveF[g[start->number][0] - 65][p1->number];
if (j>0)
{
for (k = 0; k<j&&flag == 0; k++)
{
i--;
if (i == 0)
{
flag = 1;
//如 找到p1:A->B child:带有id的leaf
addhaveF(child, p1);
guiYueOrderhead = guiYueOrderhead->last;
guiYueOrderhead->next = NULL;
}
}
}
if (flag == 0)
{
//中途遇到产生式左边与当前产生式左边一样的
if (g[p1->number][0] == g[start->number][0])
{
i++;
}
p1 = p1->last;
}
}
return guiYueOrderhead;
}
//构建语法分析树:语法树规约结束 从下往上建
void newGrammarTree()
{
Stack *ppp;
Tree *child;
//guiYueOrderhead一开始处于最底端 要不断的找他的last
while (guiYueOrderhead)
{
//第一条规约规则 当前guiYueOrderhead_haveF为root
if (guiYueOrderhead->number == 1)
{
root = guiYueOrderhead->haveF;
guiYueOrderhead = guiYueOrderhead->last;
}
else{
ppp = guiYueOrderhead;
//只有终结符的 创建leaf节点
if (guiYueOrderhead->flag == -1)
{
// B->id 创建一个leaf节点 里面存的是规约index和id的具体值
child = creatleaf(guiYueOrderhead);
//B->id 建完leaf节点要让leaf找到他的haveF,从当前的规约顺序guiYueOrderhead开始
guiYueOrderhead = findhaveF(guiYueOrderhead, child);
}
else
{
//如果是非终结符 A->B
child = guiYueOrderhead->haveF;
guiYueOrderhead = findhaveF(guiYueOrderhead, child);
}
}
//guiYueOrderhead = guiYueOrderhead->last;
//guiYueOrderhead->next = NULL;
}
}
//前序遍历得到的序列 p1:语法树root h:节点
Stack *creatGrammarTreePreOrder(Tree *p1, Stack *h)
{
Stack *pp, *p2;
pp = (Stack*)malloc(sizeof(Stack));
pp->number = p1->number;
if (p1->bb)
strcpy(pp->bb, p1->bb);
pp->next = NULL;
if (h == NULL)
{
h = pp;
}
else h->next = pp;
if (p1->child[0])
{
p2 = creatGrammarTreePreOrder(p1->child[0], pp);
if (p1->child[1])
{
while (p2)
{
pp = p2;
p2 = p2->next;
}
p2 = creatGrammarTreePreOrder(p1->child[1], pp);
if (p1->child[2])
{
while (p2)
{
pp = p2;
p2 = p2->next;
}
p2 = creatGrammarTreePreOrder(p1->child[2], pp);
if (p1->child[3])
{
while (p2)
{
pp = p2;
p2 = p2->next;
}
p2 = creatGrammarTreePreOrder(p1->child[3], pp);
}
}
}
}
return h;
}
//具体的语义分析操作
Stack *semanticsAnalysisDetail(Stack *h)
{
int l1, l2, l3, t1, t, i;
char str1[128], str2[128];
Stack *p;
p = h;
h = h->next;
if (p->number == 9)
{
h = semanticsAnalysisDetail(h);
printf("%s=%s
", p->bb, str);
}
//if then
else if (p->number == 11)
{
L++;
l1 = L;
L++;
l2 = L;
h = semanticsAnalysisDetail(h);//继续往下
printf("if (%s) gt L%d
gt L%d
", Bool, l2, l1);
printf("L%d:", l2);
grammarTreePreorderHead = semanticsAnalysisDetail(h);
printf("L%d:
", l1);
}
else if (p->number == 12)
{
L++;
l1 = L;
L++;
l2 = L;
L++;
l3 = L;
h = semanticsAnalysisDetail(h);
printf("if (%s) gt L%d
gt L%d
", Bool, l2, l3);
printf("L%d:", l2);
h = semanticsAnalysisDetail(h);
printf("gt L%d
", l1);
printf("L%d:", l3);
h = semanticsAnalysisDetail(h);
printf("L%d:
", l1);
}
else if (p->number == 13)
{
L++;
l1 = L;
L++;
l2 = L;
L++;
l3 = L;
printf("
L%d:", l1);
h = semanticsAnalysisDetail(h);
printf("if (%s) gt L%d
gt L%d
", Bool, l2, l3);
printf("L%d:", l2);
h = semanticsAnalysisDetail(h);
printf("gt L%d
", l1);
printf("L%d:
", l3);
}
else if (p->number == 14)
{
h = semanticsAnalysisDetail(h);
strcpy(Bool, str);
str[0] = '<';
str[1] = ' ';
strcat(Bool, str);
h = semanticsAnalysisDetail(h);
strcat(Bool, str);
}
//str(全局)存的是addr
else if (p->number == 15 || p->number == 17)
{
h = semanticsAnalysisDetail(h);
strcpy(str1, str);
h = semanticsAnalysisDetail(h);
strcpy(str2, str);
T++;
t1 = T;
str[0] = 't';
i = 1;
while (t1)
{
t = t1 % 10;
t1 = (t1 - t) / 10;
str[i] = t + 48;
i++;
}
str[i] = ' ';
if (p->number == 15)
printf("%s=%s+%s
", str, str1, str2);
else printf("%s=%s*%s
", str, str1, str2);
}
//赋值
else if (p->number == 16 || p->number == 18)
{
h = semanticsAnalysisDetail(h);
}
else if (p->number == 19 || p->number == 20)
{
strcpy(str, p->bb);
}
else if (p->number == 1 || p->number == 8)
{
h = semanticsAnalysisDetail(h); h = semanticsAnalysisDetail(h);
}
else if (p->number == 3 || p->number == 4 || p->number == 5 || p->number == 7 || p->number == 10)
{
h = semanticsAnalysisDetail(h);
}
return h;
}
//语义分析
void semanticsAnalysis(){
grammarTreePreorderHead = creatGrammarTreePreOrder(root, grammarTreePreorderHead);
//该序列遍历: 相当于自顶向下分析
while (grammarTreePreorderHead)
{
grammarTreePreorderHead = semanticsAnalysisDetail(grammarTreePreorderHead);
}
}
int main(){
/*
读输入文件
*/
FILE *fp;
if ((fp = fopen("in.txt", "r")) == NULL)
{
printf("cannot open the file!
");
exit(0);
}
/*
初始化词法分析
*/
initMorphology();
/*
初始化语法分析表
*/
initGrammar();
/*
将输出写文件
*/
freopen("out.txt", "w", stdout);
/*
词法分析
*/
char ch;
printf("词法分析:
");
while (!feof(fp))
{
ch = fgetc(fp);
if (ch == '
')
line++;//行号
if (feof(fp))
break;
fseek(fp, -1L, 1);//读指针退一位 所以传入的是fp
if ((ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z'))
{
keyword(fp);
}
else
{
if (ch>'0'&&ch <= '9')
{
number(fp, 1);
}
else if (ch == '0')
{
ch = fgetc(fp);
ch = fgetc(fp);
if (ch == 'x' || ch == 'X')
{
number36(fp);
}
else
{
fseek(fp, -1L, 1);
number(fp, 1);
}
}
else
{
other(fp);
}
}
}
addWordNodeEnd();
printf("
语法分析:
");
grammarAnalysis();
if (ok){//用于判断是否有文法错误
printf("
语义分析:
");
noendNumToflag();
newGrammarTree();
semanticsAnalysis();
}
fclose(stdout);
return 0;
}