#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)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)