#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
}
越哥,我来答啦,分给我吧O(∩_∩)O哈哈~/* 1 E →TE′2 E′ →+TE`
3 E′ →ε
4 T → FT′
5 T′ → * FT′
6 T′ →ε
7 F →(E)
8 F →id
FIRST(E) = FIRST(T) = FIRST(F) = { ( , id }
FIRST(E′) = {+, ε}
FRIST(T′) = {*, ε}FOLLOW(E) = FOLLOW(E′) = { ), $}
FOLLOW(T) = FOLLOW (T′) = { +, ), $}
FOLLOW(F) = {+, *, ), $} */#include <stdio.h>
#include <tchar.h>
#include <string.h>int main(int argc, char* argv[])
{
char syn[15] //语法栈
int top //栈顶指针
char lookahead //当前单词
char exp[50]//表达式区
int m =0 //表达式指针
char s[4][5]={"id","+","*","("} //表中有空白的符号
char string[3]={'E','T','F'} //表中有同步记号的的非终结符
int ll1[7][6]={
{1,0,0,1,9,9}, //LL(1)分析表,9表示同步记号,第6行是#,第7行是)
{0,2,0,0,3,3},
{4,9,0,4,9,9},
{0,6,5,0,6,6},
{8,9,9,7,9,9},
{12,12,12,12,12,10},
{13,13,13,13,11,13}}
int i,j //表行和列
int code //表项
printf("******************语法分析器********************\n")
printf("please input your expression:\n")
scanf("%s",exp)
top=1
lookahead=exp[m++]
syn[0]='#'
syn[1]='E'
while(1)
{
switch(syn[top])//行
{
case 'E':i=0break
case 'e':i=1break
case 'T':i=2break
case 't':i=3break
case 'F':i=4break
case '#':i=5break
case ')':i=6break
}
switch(lookahead) //列
{
case 'i':j=0break
case '+':j=1break
case '*':j=2break
case '(':j=3break
case ')':j=4break
case '#':j=5break
}
code=ll1[i][j]
if(code==10)
{ printf("语法分析结束\n")
break}
else
{
switch(code)
{
case 0:
{
printf("出错,用户多输入了%s,跳过%s\n",s[j],s[j])
if(j==0)
{lookahead=exp[m++]<br>lookahead=exp[m++]}
else
lookahead=exp[m++]
break
}
case 1:{printf("E →TE′\n")syn[top]='e'syn[top+1]='T'top++break}
case 2:{printf("E′ →+TE`\n")syn[top+1]='T'top++lookahead=exp[m++]break}
case 3:{printf("E′ →ε\n")syn[top]='\0'top--break}
case 4:{printf("T → FT′\n")syn[top]='t'syn[top+1]='F'top++break}
case 5:{printf("T′ → * FT′\n")syn[top+1]='F'top++lookahead=exp[m++]break}
case 6:{printf("T′ →ε\n")syn[top]='\0'top--break}
case 7:{printf("F →(E)\n")syn[top]=')'syn[top+1]='E'top++lookahead=exp[m++]break}
case 8:{printf("F →id\n")syn[top]='\0'top--lookahead=exp[m++]lookahead=exp[m++]break}
case 9:{printf("d栈,d出非终结符%c,用户少输入了一个id\n",string[i/2])syn[top]='\0'top--break}
case 11:{syn[top]='\0'top--lookahead=exp[m++]break}
case 13:{printf("d栈,d出终结符 ) ,用户少输入了一个右括号\n")syn[top]='\0'top--break}
}
}
}
return 0
}
在编译原理中,语法规则和词法规则不同之处在于:规则主要识别单词,而语法主要识别多个单词组成的句子。词法分析和词法分析程序:
词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。词法分析程序实现这个任务。词法分析程序可以使用lex等工具自动生成。
语法分析(Syntax analysis或Parsing)和语法分析程序(Parser)
语法分析是编译过程的一个逻辑阶段。语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述.
语义分析(Syntax analysis)
语义分析是编译过程的一个逻辑阶段. 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查, 进行类型审查.语义分析将审查类型并报告错误:不能在表达式中使用一个数组变量,赋值语句的右端和左端的类型不匹配.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)