熟悉编译原理及C++编译器的朋友请进
本站资源中的一个c子集编译器的代码,没看懂,请懂的朋友指教,以期比较快理解这个代码。
原代码更长,只贴些关键的代码。
,"sssss","ssss","ss","ssssssssssss","rsr","rrr","ssssssssssss","rsrr","rrsrr"
,"rrsrrr","rrrrrr","rrrrrr","s","s","rrrrrrrr","s","s","ssssssssssss","s"
,"rrrrrrrr","rrr","rrrrrrrr"};
//状态的个数 3、似乎是指某个规约的符号串的长度
int cal[84]={2,1,1,1,1,1,12,1,13,1,1,1,1,1,2,1,1,1,1,1,1,10,6,6,8,2,2,8,1,2,3,3,6,7,1,2,2,4,5,6,
6,8,6,6,1,2,1,5,4,2,3,1,1,1,1,3,3,3,3,1,7,6,5,4,2,12,3,3,12,4,5,6,6,6,1,1,8,1,1,12,1,8,3,8};
//以上状态在action和goto中对应的列 4、以下似乎是语法规则?
char Let[][14]=
{
{'v','Q'},
{'$'},
{'m'},
{'('},
{')'},
{'{'},
{'i','a','b','c','d','f','w','A','C','X','Y','S'},
{'}'},
{'i','}','a','b','c','d','f','w','A','C','X','Y','S'},
{';'},
{'('},
{'('},
{'='},
{';'},
{'i','Z'},
{'i'},
{'i'},
{'i'},
{'i'},
{'$'},
{'}'},
{'i','a','b','c','d','f','w','X','Y','S'},
{'i','!','(','E','H','G'},
{'i','!','(','E','H','G'},
{'i','(','n','L','I','K','T','F'},
{',',';'},
{',',';'},
{'i','}','a','b','c','d','f','w'},
{';'},
{'&',')'},
{'&','|',')'},
{'&','|',')'},
{'i','!','(','E','H','G'},
{'&','|','<','>','@','#',')'},
{'i'},
{'&',')'},
{'+',';'},
{'+','-',';',')'},
{'+','-','/',';',')'},
{'+','-','*','/',';',')'},
{'+','-','*','/',';',')'},
{'i','(','n','L','I','K','T','F'},
{'+','-','*','/',';',')'},
{'+','-','*','/',';',')'},
{'i'},
{',',';'},
{'{'},
{'i','!','(','H','G'},
{'i','!','(','G'},
{'&',')'},
{'&','|',')'},
{'i'},
{'i'},
{'i'},
{'i'},
{'&','|',')'},
{'&','|',')'},
{'&','|',')'},
{'&','|',')'},
{'{'},
{'i','(','n','I','K','T','F'},
{'i','(','n','K','T','F'},
{'i','(','n','T','F'},
{'i','(','n','F'},
{'+',')'},
{'i','a','b','c','d','f','w','A','C','X','Y','S'},
{'&','|',')'},
{'&','|',')'},
{'i','a','b','c','d','f','w','A','C','X','Y','S'},
{'+','-',';',')'},
{'+','-','/',';',')'},
{'+','-','*','/',';',')'},
{'+','-','*','/',';',')'},
{'+','-','*','/',';',')'},
{'}'},
{'}'},
{'i','}','a','b','c','d','f','w'},
{'e'},
{'{'},
{'i','a','b','c','d','f','w','A','C','X','Y','S'},
{'}'},
{'i','}','a','b','c','d','f','w'},
{'&','|',')'},
{'i','}','a','b','c','d','f','w','}'}
};
//初始化关系表
for(int i=0;i<84;i++){
for(int j=0;j<cal[i];j++){
r_new=(Relation *)malloc(sizeof(Relation));
if(r_head==NULL){
r_find=r_head=r_new;
}
r_new->line_States=i;
r_new->rank_Letter=Let[i][j];
r_new->relationship=sr[i][j];
r_new->name=SS[i][j];
r_find->next=r_new;
r_find=r_new;
r_new->next=NULL;
}
}
return r_head;
}
//初始化规则表函数: Guiyue *guiyue()
//数据传递: g_head返回规则表的头指针
Guiyue *FirstGuiyue(){
Guiyue *g_head,*g_find,*g_new;
g_head=NULL;
//规约 5、这些大写字母什么意义?
char root[]={'B','Q','S','A','A','C','C','X','Y','Y','Y','Y','Z','Z','S','S','S','E','E','H',
'H','G','G','G','G','G','G','G','L','L','I','I','K','K','T','T','F','F','F'};
//6、这些数字是优先级?
int LR[]={1,7,3,2,1,3,1,2,1,1,1,1,3,1,11,7,4,3,1,3,1,3,3,3,3,3,2,1,3,1,3,1,3,1,3,1,3,1,1};
//初始化规则表
for(int i=0;i<39;i++){
g_new=(Guiyue *)malloc(sizeof(Guiyue));
if(g_head==NULL){
g_find=g_head=g_new;
}
g_new->num=i;
g_new->count=LR[i];
g_new->name=root[i];
g_find->next=g_new;
g_find=g_new;
g_new->next=NULL;
}
return g_head;
}
///语法分析函数:
// 数据传递: 1 *r_head:分析表头指针.
// 2 *s_head:符号栈头指针.
// 3 str[] :转义字符流.
// 4 *g_head:规则表头指针.
// 5 cal :转义字符流的长度.
int ResultAnely(Relation *r_head,Stack *s_head,char str[],Guiyue *g_head,int cal){
Relation *r_find;
Guiyue *g_find;
Stack *s_find,*s_look;
s_find=s_head;
int j,v,admition=1,goon=1,in,out=1,hang=-1,count;
char stack[200],name;
while(goon){//:1
int admit=1;
r_find=r_head;
g_find=g_head;
hang++;
while(r_find&&admit){//:2
if(r_find->line_States==s_find->num&&r_find->rank_Letter==str[0]&&r_find->name=='s'){//:入栈
s_find=MarkPush(s_find,str[0],r_find->relationship);
admit=0;//跳出
for(in=0;in<cal-1;in++)//向前移1byte
{
str[in]=str[in+1];
}
str[in]='\0';
cal--;
r_find=r_find->next;
}//:入栈~
if(r_find->line_States==s_find->num&&r_find->rank_Letter==str[0]&&r_find->name=='r'){//:规约
g_find=g_head;
int g=r_find->relationship;
while(g)
{
g_find=g_find->next;
g--;
}
name=g_find->name;
count=g_find->count;
admit=0;
for(int k=0;k<count;k++){
MarkPop(s_find);
}
r_find=r_head;
int a=1;
while(r_find&&a){
if(r_find->line_States==s_find->num && r_find->rank_Letter==name)
{
s_find=MarkPush(s_find,name,r_find->relationship);
a=0;
}
r_find=r_find->next;
}
}//:规约~
if(r_find->line_States==s_find->num&&r_find->rank_Letter==str[0]&&r_find->name=='o'){//:2判断运算结束
admit=0;
goon=0;
out=0;
cout<<"\nSuccession !"<<endl;
return(1);
}
r_find=r_find->next;
}//:2~
if(admit==1){ //判断输入流是否正确,如在分析表中找不到关系,则输入流错误
goon=0;
cout<<"\nInput Flow Error !"<<endl;
return(0);
}
}//1:~
cout<<"\n****************************************\n"<<endl;
}
[解决办法]
只需弄懂每个函数的功能就行了,先从整体上把握,首先上来不要纠结于细节,待整体把握后,有兴趣可深究内部具体实现过程
[解决办法]
看这个还不如看编译原理的书.
无非就是几个状态转换表....
[解决办法]
这个的话题太太太长了,完全解释不起啊~~
你去翻翻 龙书 吧
[解决办法]
++
[解决办法]
这绝对不是龙书,是中国大陆大学自己编的《编译原理》吧?
[解决办法]
还是建议lz先读读编译原理吧
[解决办法]
嗯,编译原理。
[解决办法]
还不如去下载研究LEX+YACC呢。
[解决办法]
一般来说复杂语言的编译器都是机器生成的,比如说用Bison(yacc)或者ANTLR写语法文件,然后用他们生成C/C++的编译器代码。如果代码是这些软件生成的,你直接看代码是看不懂的。从文件开头的注释或者代码风格可以看出该代码是否是机器生成的代码。
你给的代码好像用了拼音作为结构名(GuiYue),很可能还真的是人写的。
如果你非要看懂这段代码,首先你先要搞明白这个编译器是LR\LALR\LL(*)中的哪一种。Google parser和这三个名字你就知道我在说什么。每一种语元的读取顺序都会导致编译器代码的很大区别。在搞清除了这个之后,编译器的结构实际上也就固定了。你就可以将代码中的数据结构套到对应的编译器结构中从而理解代码。
手写编译器有很多坏处,比如不好维护,删减或添加些语言特性要做很多修改。还有代码的可读性非常差。所以现在的实际做法都是用软件自动生成编译器。如果你非要用这段代码,的确需要看看龙书或者虎书。如果你只是想学习写编译器或者要就是要马上造一个编译器,直接学Bison或者ANTLR的软件用法和语法结构就好了。龙虎书都是教你手写编译器,可现在不需要了。