词法分析以及文法描述词法规则的己见

一.词法分析程序的功能。

    词法分析程序完成的事编译第一阶段的工作。词法分析工作可以使独立的一遍,把字符流的源程序变成单词序列,输出到一个中间文件,这个文件作为语法分析程序的恶输入而继续的编译过程。对字符串表示的源程序从左到右进行扫描和分解根据词法规则,识别出一个一个具有独立意义的单词符号以供语法分析之用。发现词法错误则返回出错信息。

 

二。符号与种别码的对照表以及源程序。

      我所做的词法分析程序和大多数程序差不多,也有着很多的不足,我将需要进行翻译的各种单词符号的对应的种别码分成了若干个数组,并且在后期的修改中将老师的种别表进行了扩充,具体的功能是:输入需要翻译的东西作为字符串存储在A[][]的数组中,用字符ch来存储一个个的字符,在一次的循环中翻译出一个个种别类并将其用(,)来显示出来,一次循环,用数组TOKEN[]存储,进行下一次循环的同时清除里面的数据,方便进行下一次的翻译与存储。大致是如此。

     源代码如下:

  

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char TOken[10];//分开进行比较
char ch;
/*char rwtab[6]={"begin","if","then","while","do","end"};*/
char r1[]={"auto"};
char r2[]={"break"};
char r3[]={"case"};
char r4[]={"char"};
char r5[]={"const"};
char r6[]={"continue"};
char r7[]={"default"};
char r8[]={"do"};
char r9[]={"double"};
char r10[]={"else"};
char r11[]={"enum"};
char r12[]={"extern"};
char r13[]={"float"};
char r14[]={"for"};
char r15[]={"goto"};
char r16[]={"if"};
char r17[]={"int"};
char r18[]={"long"};
char r19[]={"register"};
char r20[]={"return"};
char r21[]={"short"};
char r22[]={"signed"};
char r23[]={"sizeof"};
char r24[]={"static"};
char r25[]={"struct"};
char r26[]={"switch"};
char r27[]={"typedef"};
char r28[]={"union"};
char r29[]={"unsigned"};
char r30[]={"void"};
char r31[]={"volatile"};
char r32[]={"while"};
char r33[]={"end"};
char r34[]={"include"};
char r35[]={"stdio"};
char r36[]={"string"};
char r37[]={"main"};
char r38[]={"stdlib"};//这是我定义的
char A[10000];//输入的所有值
int syn,row;
int n,m,p,sum,j;
static int i = 0;
void scaner();
int main()
{
row = 0 ;
p = 0 ;
printf("Please input string:(end of '@')\n");
do
{
scanf("%c",&ch);
A[p]=ch;
p++;
}//输入值到数组A【】中,以@结束
while(ch!='@');
do
{
scaner();//进入函数进行判定
switch(syn)
{
case 40: printf("(%d,%d)\n",syn,sum); break;//如果是40,那么就是数字
case 0: printf("(%d,%c)\n",syn,TOken[0]);break;//如果是0,那么是@ 结束
case -2: row=row++;break;
default: printf("(%d,%s)\n",syn,TOken);break;//否则,就是变量名、关键词
}
}
while (syn!=0);
}
void scaner()
{
/*
共分为三大块,分别是标示符、数字、符号,对应下面的 if else if 和 else


*/
for(n=0;n<7;n++)
TOken[n]=0;//每次循环完就清零
ch=A[i];
while(ch==' '||ch=='\n')//如果字符是空格或者回车,跳过
{
i++;
ch=A[i];
}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) //可能是标示符或者变量名
{
m=0;
while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))//找到一个变量名或者关键字,直到遇到空格为止
{
TOken[m]=ch;m++;
i++;ch=A[i];
}
TOken[m]='\0';
//将识别出来的字符和已定义的标示符作比较, //因为定义的begin为1,if为2......
if(strcmp(TOken,r1)==0){syn=1;}
else if(strcmp(TOken,r2)==0){syn=2; }
else if(strcmp(TOken,r3)==0){syn=3;}
else if(strcmp(TOken,r4)==0){syn=4;}
else if(strcmp(TOken,r5)==0){syn=5;}
else if(strcmp(TOken,r6)==0){syn=6;}
else if(strcmp(TOken,r7)==0){syn=7;}
else if(strcmp(r8,TOken)==0){syn=8;}
else if(strcmp(r9,TOken)==0){syn=9;}
else if(strcmp(r10,TOken)==0){syn=10;}
else if(strcmp(r11,TOken)==0){syn=11;}
else if(strcmp(r12,TOken)==0){syn=12;}
else if(strcmp(r13,TOken)==0){syn=13;}
else if(strcmp(r14,TOken)==0){syn=14;}
else if(strcmp(r15,TOken)==0){syn=15;}
else if(strcmp(r16,TOken)==0){syn=16;}
else if(strcmp(r17,TOken)==0){syn=17;}
else if(strcmp(r18,TOken)==0){syn=18;}
else if(strcmp(r19,TOken)==0){syn=19;}
else if(strcmp(r20,TOken)==0){syn=20;}
else if(strcmp(r21,TOken)==0){syn=21;}
else if(strcmp(r22,TOken)==0){syn=22;}
else if(strcmp(r23,TOken)==0){syn=23;}
else if(strcmp(r24,TOken)==0){syn=24;}
else if(strcmp(r25,TOken)==0){syn=25;}
else if(strcmp(r26,TOken)==0){syn=26;}
else if(strcmp(r27,TOken)==0){syn=27;}
else if(strcmp(r28,TOken)==0){syn=28;}
else if(strcmp(r29,TOken)==0){syn=29;}
else if(strcmp(r30,TOken)==0){syn=30;}
else if(strcmp(r31,TOken)==0){syn=31;}
else if(strcmp(r32,TOken)==0){syn=32;}
else if(strcmp(r33,TOken)==0){syn=33;}
else if(strcmp(r34,TOken)==0){syn=34;}
else if(strcmp(r35,TOken)==0){syn=35;}
else if(strcmp(r36,TOken)==0){syn=36;}
else if(strcmp(r37,TOken)==0){syn=37;}
else if(strcmp(r38,TOken)==0){syn=38;}
else{syn=100;} //变量名
}
else if((ch>='0'&&ch<='9')) //数字
{
sum=0;
while((ch>='0'&&ch<='9'))
{
sum=sum*10+ch-'0';//显示其数字sum
i++;
ch=A[i];
}
syn=40;
}
else switch(ch) //其他字符
{
case'<':m=0;TOken[m]=ch;m++;
i++;ch=A[i];
if(ch=='=')//<>为22
{
syn=41;
TOken[m]=ch;m++;i++;
}
else
{
syn=46;
}
break;
case'>':m=0;TOken[m]=ch;m++;
i++;ch=A[i];
if(ch=='=')
{
syn=42;
TOken[m]=ch;m++;i++;
}
else
{
syn=47;
}
break;
case':':m=0;TOken[m]=ch;m++;
i++;ch=A[i];
if(ch=='=')
{
syn=44;
TOken[m]=ch;m++;i++;
}
else
{
syn=49;
}
break;
case'@':syn=0;TOken[0]=ch;i++;break;
case'=':syn=48;TOken[0]=ch;i++;break;
case'#':syn=50;TOken[0]=ch;i++;break;
case'+':syn=50;TOken[0]=ch;i++;break;
case'-':syn=51;TOken[0]=ch;i++;break;
case'*':syn=52;TOken[0]=ch;i++;break;
case'/':syn=53;TOken[0]=ch;i++;break;
case'(':syn=54;TOken[0]=ch;i++;break;
case')':syn=55;TOken[0]=ch;i++;break;
case'{':syn=56;TOken[0]=ch;i++;break;
case'}':syn=57;TOken[0]=ch;i++;break;
case';':syn=58;TOken[0]=ch;i++;break;
case'.':syn=59;TOken[0]=ch;i++;break;
case'\'':syn=60;TOken[0]=ch;i++;break;
case'\n':syn=-2;break;
default: syn=-1;break;
}
}

/*这是我定义的种别类 符号:

@ 0 # 33
auto 1 
break 2 
case 3 
char 4 
const 5 
continue 6 
default 7 
do 8 
double 9 
else 10 
enum 11 
extern 12
float 13 
for 14 
goto 15 
if 16 
int 17 
long 18
register 19 
return 20
short 21
signed 22
sizeof 23
static 24
struct 25
switch 26
typedef 27
union 28
unsigned 29
void 30
volatile 31
while 32
end 33
include 34
stdio 35
string 36
main 37
stdlib 38
qita 100
number 40

#      33

<=     41

>=     42

==     43

:=     44

<>     45

<      46

>      47

 =      48

:      49

+  50

-  51

*  52 

/  53

(  54

)  55

{  56

}  57

;  58

.  59

*/

程序运行如下:

 

三 .用文法描述词法规则。

    这个概念我不是太懂,但是也说说自己的理解和想法。

     首先是文法形式的定义:A-〉B ,A代表的是左部符号,‘-〉’意思是为生成,而B代表的是右部的符号串。

     有着终结符号:如0,1:1.组成语言的终止符。2.基本有小写字母组成。

     文法(Vn,Vt,P,S)

   就比如说:A->a|b|e|Aa|Ae|Ao|A

                Vn = {A},

                 Vt ={a,b,c,d,e,0,1}

                P={A->a|b|e|Aa|Ae|Ao|A}

               S = A .

      其实A-〉Aa 就代表着循环的意思,每进行一次,就会增加一个a,假如A-〉Aaa,意思就是每循环一次,就增加aa,所以暂时也就是理解到了这个意思,然后通过几道题来强化自己的理解。

      就好比Q={a,b},L={a^2n ,b^2n|n>=1}

     首先是看好n的取值范围,然后看n具体指了多少个,那么就比如一起来进行循环,这个题a,b都有n,但是是分开的,所以不用一起进行。

     解题思路如下:

     1.增长的趋势:a^2n,aa aaaa aaaaaa........

                        b^2n,bb bbbb bbbbbb.......

    2.循环规律:A->aa  A->Aaa

                     B->bb B->Bbb

    3.S->A|B

     A->aa|Aaa // 意思是aa为开头,循环不断增加aa

     B->bb|Bbb // 意思是bb为开头,循环不断增加bb

     大概就这样。嗯

     可以做几道典型题型来试一试。{ab^n a|n>=0} {a^m b^m|n>=1 m>=1}等等

 201506110166 黄仲浩

转载于:https://www.cnblogs.com/qazwsx833/p/5924053.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值