求 编译原理 语法分析程序

求 编译原理 语法分析程序,第1张

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <stack>

using namespace std

struct Node1

{

char vn

char vt

char s[10]

}MAP[20]//存储分析预测表每个位置对应的终结符,非终结符,产生式

int k

//用R代表E',W代表T',e代表空

char G[10][10]={"E->TR","R->+TR","R->e","T->FW","W->*FW","W->e","F->(E)","F->i"}//存储文法中的产生式

char VN[6]={'E','R','T','W','F'}//存储非终结符

char VT[6]={'i','+','*','(',')','#'}//存储终结符

char SELECT[10][10]={"(,i","+","),#","(,i","*","+,),#","(","i"}//存储文法中每个产生式对应的SELECT集

char Right[10][8]={"->TR","->+TR","->e","->FW","->*FW","->e","->(E)","->i"}

stack <char>stak,stak1,stak2

bool compare(char *a,char *b)

{

int i,la=strlen(a),j,lb=strlen(b)

for(i=0i<lai++)

for(j=0j<lbj++)

{

if(a[i]==b[j])

return 1

}

return 0

}

char *Find(char vn,char vt)

{

int i

for(i=0i<ki++)

{

if(MAP[i].vn==vn &&MAP[i].vt==vt)

return MAP[i].s

}

return "error"

}

char * Analyse(char * word)

{

char p,action[10],output[10]

int i=1,j,l=strlen(word),k=0,l_act,m

while(!stak.empty())

stak.pop()

stak.push('#')

stak.push('E')

printf("________________________________________________________________________________\n")

printf("\n对符号串%s的分析过程\n",word)

printf("步骤栈顶元素剩余输入串推到所用产生式或匹配\n")

p=stak.top()

while(p!='#')

{

printf("%7d ",i++)

p=stak.top()

stak.pop()

printf("%6c ",p)

for(j=k,m=0j<lj++)

output[m++]=word[j]

output[m]='\0'

printf("%10s",output)

if(p==word[k])

{

if(p=='#')

{

printf("接受\n")

return "SUCCESS"

}

printf(" “%c”匹配\n",p)

k++

}

else

{

strcpy(action,Find(p,word[k]))

if(strcmp(action,"error")==0)

{

printf("没有可用的产生式\n")

return "ERROR"

}

printf("%c%s\n",p,action)

int l_act=strlen(action)

if(action[l_act-1]=='e')

continue

for(j=l_act-1j>1j--)

stak.push(action[j])

}

}

if(strcmp(output,"#")!=0)

return "ERROR"

}

int main ()

{

freopen("in.txt","r",stdin)

//freopen("out.txt","w",stdout)

char source[100]

int i,j,flag,l,m

printf("\n*****为了方便编写程序,用R代表E',W代表T',e代表空*****\n\n")

printf("该文法的产生式如下:\n")

for(i=0i<8i++)

printf(" %s\n",G[i])

printf("________________________________________________________________________________\n")

printf("\n该文法的SELECT集如下:\n")

for(i=0i<8i++)

{

printf(" SELECT(%s) = { %s }\n",G[i],SELECT[i])

}

printf("________________________________________________________________________________\n")

//判断是否是LL(1)文法

flag=1

for(i=0i<8i++)

{

for(j=i+1j<8j++)

{

if(G[i][0]==G[j][0])

{

if(compare(SELECT[i],SELECT[j]))

{

flag=0break

}

}

}

if(j!=8)

break

}

if(flag)

printf("\n有相同左部产生式的SELECT集合的交集为空,所以文法是LL(1)文法。\n")

else

printf("\n有相同左部产生式的SELECT集合的交集不为空,所以文法不是LL(1)文法。\n")

printf("________________________________________________________________________________\n")

//预测分析表

for(i=0,k=0i<8i++)

{

l=strlen(SELECT[i])

for(j=0j<lj+=2)

{

MAP[k].vn=G[i][0]

MAP[k].vt=SELECT[i][j]

strcpy(MAP[k].s,Right[i])

k++

}

}

printf("\n表达式文法的预测分析表如下:\n\n")

printf(" ")

for(i=0i<6i++)

printf("%10c",VT[i])

printf("\n")

for(i=0i<5i++)

{

printf("---------------------------------------------------------------\n")

printf("%10c",VN[i])

for(j=0j<6j++)

{

for(m=0m<km++)

{

if(VN[i]==MAP[m].vn &&VT[j]==MAP[m].vt)

{

printf("%10s",MAP[m].s)

break

}

}

if(m==k)

printf(" ")

}

printf("\n")

}

/*预测分析程序

Analyse函数*/

//输入源文件串

while(cin>>source)

{

printf("\n分析结果:%s\n\n",Analyse(source))

}

while(1)

return 0

}

嘿嘿,这个我做过哦。是编译原理的东西。

不过现在没有程序,没带来,给你一个参考的:虽然不是完全符合你的要求。不过其中很多函数你是要用到的,比如词法分析部分,其实你的要求就是进行词法分析的,无非你用scanf(),你用词法分析,分析出scanf()语句,再进行内部参数分析,就OK了;

祝你成功哦

///////////////////////////////////////////////////////////////////

for循环语句翻译 递归下降法 输出三地址码 /////////////

#define MAX 100

#include<iostream.h>

#include<stdio.h>

#include<string.h>

char str[MAX]

char ch

int turn

char strToken[MAX]

int kind

int n=0//存放strtoken[]元素的个数

struct Word//结构体 存放单词

{

int sort

char word[MAX]//存放strtoken[]的内容

}

//record[x]=new Word

Word *record[12]//放所有识别出来的单词,分别存放他们的编号以及字符串,x是其下标

////////////////////词法分析///////////////////////

int buffer()//载入

{

int i=0

cout<<"输入程序,以“#”作为结束标志。"<<endl

for(int n=0n<=MAXn++)

{

for(i<=MAXi++)

{

scanf("%c",&str[i])

/////////////cin>>str[i]不可用,用C语言读入字符。

if(str[i]=='#')

break///////如果尾数为识别码#,则表示程序读完,跳出循环.

}

break

}

return(i)

}

bool IsLetter(char ch)///////////判断是否是字母

{

if(ch>=65&&ch<=90||ch>=97&&ch<=122)

return(true)

else

return(false)

}

bool IsDigit(char ch)//////////判断是否是数字

{

if(ch>=48&&ch<=57)

return(true)

else

return(false)

}

char GetChar(int i)///////读取字符

{

char ch

ch=str[i]

return(ch)

}

char GetBC(char ch)////判断是不是空格或者换行,如果是,直接读取下一个字符直道不再空白为止

{

if(ch==32||ch==10)

{

turn++

ch=GetChar(turn)

ch=GetBC(ch)/////////递归实现

return(ch)

}

else

return(ch)

}

void Concat()/////////////连接,即为strtoken[]赋值

{

strToken[n]=ch

n++

}

int Reserve()/////以单词为单位查找保留字,是则返回编码,不是则返回0,用来区分标志符和保留字

{

if(strcmp(strToken," DIM\0")==0)///////调用strcmp函数实现,

return(1)

else if(strcmp(strToken,"for\0")==0)

return(2)

else if(strcmp(strToken,"step\0")==0)

return(3)

else if(strcmp(strToken,"until\0")==0)

return(4)

else if(strcmp(strToken,"do\0")==0)

return(5)

else

return(6)

}

void clear()

{

n=0

}

/////////////*语法递归分析*/////////////////

int A(int * c,int &q)

{

if(c[q++]==3)

{

if(c[q]==7)

{ q++

return 1

}

else {cout<<"step右部出错"<<endlreturn 0}

}else {cout<<"error 'step'"<<endlreturn 0}

}

int B(int * b,int &o)

{

if(b[o++]==4)

{

if(b[o]==7)

{ o++

return 1

}

else {cout<<"until右部出错"<<endlreturn 0}

}else {cout<<"error 'until'"<<endlreturn 0}

}

int S2(int * d,int &h)

{

if(d[h++]==6)

{

if(d[h++]==8)

{

if((d[h]==6||d[h]==7)) {h++return 1}

else {cout<<"赋值语句右部出错 "<<endlreturn 0}

}else {cout<<"赋值语句缺少赋值运算符 "<<endlreturn 0}

}else {cout<<"赋值语句左部出错 "<<endlreturn 0}

}

int S1(int * m,int &n)

{

if(S2(m,n))

{

if(A(m,n))

{

if(B(m,n)) return 1

else return 0

}else return 0

}else return 0

}

int S(int *a,int &z)

{

if (a[z++]==2)

{

if (S1(a,z))

{

if(a[z++]==5)

{

if(S2(a,z))

{

cout<<"succeed!"<<endlreturn 1

}else return 0

}else {cout<<"error 'do'"<<endlreturn 0}

}else return 0

}else {cout<<"error 'for'"<<endlreturn 0}

}

void main()

{

cout<<"*************产生式***************"<<endl// for step until do i j =

cout<<" S ->for S1 do S2"<<endl// 编号 2 3 4 5 6 7 8

cout<<" S1 ->S2AB"<<endl

cout<<" S2 ->i=j"<<endl

cout<<" A ->stepj"<<endl

cout<<" B ->untilj"<<endl

int num

turn=0

num=buffer()-1

int x=0//计识别的单词的个数

for(turn<=numturn++)//总循环,ch存放刚读入的字符,strtoken[]存放已识别的标志付或保留字,turn是数组str[]的下标

{

ch=GetChar(turn)

ch=GetBC(ch)

if(IsLetter(ch))

{

while(IsLetter(ch)&&turn<=num||IsDigit(ch)&&turn<=num)

{

Concat()

ch=GetChar(++turn)

}

strToken[n]='\0'

ch=NULL//此ch不是标志符中的符号

turn=turn-1

kind=Reserve()

record[x]=new Wordrecord[x]->sort=kind//12345或6

//cout<<kind//测试

cout<<"("

for(int i=0i<ni++)

{

record[x]->word[i]=strToken[i]

cout<<record[x]->word[i]//输出识别的标志符或保留字

}

cout<<","<<kind<<")"<<endl

record[x]->word[i]='\0'

clear()

x++

}

else if(IsDigit(ch))

{

while(IsDigit(ch)&&turn<=num)

{

Concat()

ch=GetChar(++turn)

}

ch=NULL

turn=turn-1

kind=7

//////////////

record[x]=new Word

record[x]->sort=kind

////////////////

cout<<"("

for(int i=0i<ni++)

{

record[x]->word[i]=strToken[i]

cout<<record[x]->word[i]

}

cout<<","<<kind<<")"<<endl

record[x]->word[i]='\0'

clear()x++

}

else if(ch=='=')

{

kind=8

///////

record[x]=new Word

record[x]->word[0]='='

record[x++]->sort=kind

cout<<"(=,"<<kind<<")"<<endl

}

else

cout<<"error input!"<<endl

}

//////////////////////*语法分析*////////////////

//int y

/*for(y=0y<xy++)

{cout<<record[y]->sort<<" "//打印单词的编号 。

}cout<<endl*/

int ana[MAX]//存放词法分析得到的单词序列的编号的序列

int m

for(m=0m<xm++)

{

ana[m]=record[m]->sort//将sort作为数组保存起来

}

/////////语法分析///////

int j=0

///////////////////制导翻译//////////////////

if(!S(ana,j)) cout<<"语法出错!"<<endl

else

{ cout<<"三地址码如下:"<<endl

cout<<"100 "

int i=0

while(record[1]->word[i]!='\0')

cout<<record[1]->word[i++]cout<<record[2]->word[0]

i=0

while(record[3]->word[i]!='\0')

cout<<record[3]->word[i++]cout<<endl

cout<<"101 goto 103"<<endl

cout<<"102 "

i=0

while(record[1]->word[i]!='\0')

cout<<record[1]->word[i++]cout<<":="

i=0

while(record[1]->word[i]!='\0')

cout<<record[1]->word[i++]cout<<"+"

i=0

while(record[5]->word[i]!='\0')

cout<<record[5]->word[i++]cout<<endl

cout<<"103 if "

i=0

while(record[1]->word[i]!='\0')

cout<<record[1]->word[i++]cout<<"<"

i=0

while(record[7]->word[i]!='\0')

cout<<record[7]->word[i++]

cout<<" goto 105"<<endl

cout<<"104 goto 107"<<endl

cout<<"105 "

i=0

while(record[9]->word[i]!='\0')

cout<<record[9]->word[i++]cout<<":="

i=0

while(record[11]->word[i]!='\0')

cout<<record[11]->word[i++]cout<<endl

cout<<"106 goto 102"<<endl

cout<<"107 end"<<endl

}

}

帮你找了一个,感觉还不错:

#include<stdio.h>

#include<malloc.h>

#define size 100

typedef char E

typedef struct{

int top

E *base

int Ssize

}Stack

void Init(Stack *S){

S->base=(E *)malloc(size*sizeof(E))

S->top=0

S->Ssize=size

}int Len(Stack S){

return(S.top)

}int Top(Stack S,E *e){

if(!S.top)return(0)

*e=S.base[S.top-1]

return(1)

}int Push(Stack *S,E e){

if(S->top>=S->Ssize){

S->base=(E *)realloc(S->base,(S->Ssize+1)*sizeof(E))

if(!S->base)return(0)

S->Ssize++

}S->base[S->top++]=e

return(1)

}int Pop(Stack *S,E *e){

if(!S->top)return(0)

*e=S->base[--S->top]

return(1)

}int isEmpty(Stack S){

if(!S.top)return(1)return(0)

}void main(){

FILE *in

Stack S

long l=1,k=0

char i[100],ch

E t

Init(&S)

printf("文件名:")

scanf("%s",i)

in=fopen(i,"r")

for(){

ch=fgetc(in)

if(ch==-1)break

else if(ch=='\\'){ch=fgetc(in)continue}

else if(ch!='\''||ch!='\"'&&!Top(S,&t)&&t=='\''||t=='\"')continue

else if(ch=='('||ch=='['||ch=='{')Push(&S,ch)

else if(ch==')'){

if(!Top(S,&t)){k++printf("第%ld行多\')\'\n")}

else if(t!='('&&t!='\''&&t!='\"'){k++printf("第%ld行\')\'用法错误\n",l)}

else if(t=='(')Pop(&S,&t)

}else if(ch==']'){

if(!Top(S,&t)){k++printf("第%ld行多\']\'\n")}

else if(t!='['&&t!='\''&&t!='\"'){k++printf("第%ld行\']\'用法错误\n",l)}

else if(t=='[')Pop(&S,&t)

}else if(ch=='}'){

if(!Top(S,&t)){k++printf("第%ld行多\'}\'\n")}

else if(t!='{'&&t!='\''&&t!='\"'){k++printf("第%ld行\'}\'用法错误\n",l)}

else if(t=='{')Pop(&S,&t)

}else if(ch=='\''||ch=='\"'){

if(!Top(S,&t)||t!=ch)Push(&S,ch)

else Pop(&S,&t)

}else if(ch=='\n')l++

}if(!isEmpty(S)){k++printf("第%ld行发现未知错误\n",l)}

if(k)printf("共%ld个错误\n",k)

else printf("无错误\n")

fclose(in)

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11082895.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存