词法分析程序的功能:
输入:源程序字符串。
输出:二元组(单词种别码,单词符号本身)。
单词符号对应的种别码:
单词符号 |
种别码 |
单词符号 |
种别码 |
begin |
1 |
: |
17 |
if |
2 |
:= |
18 |
then |
3 |
< |
20 |
while |
4 |
<= |
21 |
do |
5 |
<> |
22 |
end |
6 |
> |
23 |
Letter(letter|digit) |
10 |
>= |
24 |
digit digit |
11 |
= |
25 |
+ |
13 |
; |
26 |
- |
14 |
( |
27 |
* |
15 |
) |
28 |
/ |
16 |
# |
0 |
用文法描述词法规则:
<字母>G[S]:S->SA
A->a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|S|Y|Z
<数字> G[S]:S->S
S->0|1|2|3|4|5|6|7|8|9
- <整数常数> G[S]:S->S|SA
S->1|2|3|4|5|6|7|8|9
A->0|1|2|3|4|5|6|7|8|9
- <标识符>G[S]:S->D/SN/SD
D->a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z N->0|1|2|3|4|5|6|7|8|9
- <关键字>G[S]:S->S
S->Const| Dim|As|Mod|And|Or|Not|If|Else|Stop|End|Select|Case|Is|For|To|Step|Byref|Byval|Sub|Function|Exit|Do|Loop|Until|While|Wend|Let|Call|Rem|Integer|Long|Single|Double|Boolean|String|Me| Private|Public
- <运算符> G[S]:S->S
S->+|-|*|/|=|#|<|<=|>|>=|:=
- <界符> G[S]:S->S
S->(|),|;|.
#include<stdio.h> #include<string.h> #include<math.h> char character[80];//存放所有输入的字符 char token[8];//单词自身字符串 char ch;//单个字符 int sym;//sym:单词种别码 int p,m=0,i,row,sum=0;//sum:整型常数 char*rwtab[6]={"begin","if","then","while","do","end"}; void scanner(); void main() { p=0; row=1; printf("请输入一串字符串\n"); do { ch=getchar(); character[i++]=ch; }while(ch!='#');//输入以#号键结束 p=0; do { scanner();//识别单词 switch(sym) { case 11:printf("(%d,%d)\n",sym,sum);break; case -1:printf("error in row %d!\n",row);break; case -2:row=row++;break; default:printf("(%d,%s)\n",sym,token);break; } }while(sym!=0); } void scanner() { for(i=0;i<8;i++) token[i]=NULL; ch=character[p++]; while(ch==' ') { ch=character[p]; p++; } 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; ch=character[p++]; } token[m++]='\0'; p--; sym=10; for(i=0;i<6;i++) //将识别出来的字符和已定义的标示符作比较, if(strcmp(token,rwtab[i])==0) { sym=i+1; break; } } else if((ch>='0'&&ch<='9'))//数字 { sum=0; while((ch>='0'&&ch<='9')) { sum=sum*10+ch-'0'; ch=character[p++]; } p--; sym=11; if(sum>32767) sym=-1; } else switch(ch)//其他字符 { case'<':m=0;token[m++]=ch; ch=character[p++]; if(ch=='=') { sym=21; token[m++]=ch; } else if(ch=='>') { sym=22; token[m++]=ch; } else { sym=23; p--; } break; case'>':m=0;token[m++]=ch; ch=character[p++]; if(ch=='=') { sym=24; token[m++]=ch; } else { sym=20; p--; } break; case':':m=0;token[m++]=ch; ch=character[p++]; if(ch=='=') { sym=18; token[m++]=ch; } else { sym=17; p--; } break; case'*':sym=13;token[0]=ch;break; case'/':sym=14;token[0]=ch;break; case'+':sym=15;token[0]=ch;break; case'-':sym=16;token[0]=ch;break; case'=':sym=25;token[0]=ch;break; case';':sym=26;token[0]=ch;break; case'(':sym=27;token[0]=ch;break; case')':sym=28;token[0]=ch;break; case'#':sym=0;token[0]=ch;break; case'\n':sym=-2;break; default:sym=-1;break; } }