一個簡單詞法分析器的C語言實現
阿新 • • 發佈:2018-12-30
1.1實驗描述
例如:對源程式:
begin x:=9: if x>9 then x:=2*x+1/3; end #
的原始檔,經過詞法分析後輸出如下序列:
<1,begin><10,x><18,:=><11,9><26,;><2,if>……
1.1.1待分析的簡單的詞法
(1)關鍵字:
begin if then while do end
所有的關鍵字都是小寫。
(2)運算子和界符
: = + - * / < <= <> > >= = ; ( ) #
(3)其他單詞是識別符號(ID)和整型常數(SUM),通過以下正規式定義:
ID = letter (letter | digit)*
NUM = digit digit*
(4)空格有空白、製表符和換行符組成。空格一般用來分隔ID、SUM、運算子、界符和關鍵字,詞法分析階段通常被忽略。
1.1.2 各種單詞符號對應的種別碼:
表4.2.1 各種單詞符號對應的種別碼
單詞符號 |
種別碼 |
單詞符號 |
種別碼 |
bgin |
1 |
: |
17 |
If |
2 |
:= |
18 |
Then |
3 |
< |
20 |
wile |
4 |
<> |
21 |
do |
5 |
<= |
22 |
end |
6 |
> |
23 |
lettet(letter|digit)* |
10 |
>= |
24 |
dight dight* |
11 |
= |
25 |
+ |
13 |
; |
26 |
— |
14 |
( |
27 |
* |
15 |
) |
28 |
/ |
16 |
# |
0 |
2.2實現原始碼參考
#include <stdio.h> #include <string.h> char prog[80],token[8],ch; int syn,p,m,n,sum; char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner(void); main() { p=0; printf("\n please input a string(end with '#'):\n"); do{ scanf("%c",&ch); prog[p++]=ch; }while(ch!='#'); p=0; do{ scaner(); switch(syn) { case 11: printf("( %-10d%5d )\n",sum,syn); break; case -1: printf("you have input a wrong string\n"); //getch(); return 0; break; default: printf("( %-10s%5d )\n",token,syn); break; } }while(syn!=0); //getch(); } void scaner(void) { sum=0; for(m=0;m<8;m++) token[m++]= NULL; ch=prog[p++]; m=0; while((ch==' ')||(ch=='\n')) ch=prog[p++]; if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))) { while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9'))) { token[m++]=ch; ch=prog[p++]; } p--; syn=10; for(n=0;n<6;n++) if(strcmp(token,rwtab[n])==0) { syn=n+1; break; } } else if((ch>='0')&&(ch<='9')) { while((ch>='0')&&(ch<='9')) { sum=sum*10+ch-'0'; ch=prog[p++]; } p--; syn=11; } else { switch(ch) { case '<': token[m++]=ch; ch=prog[p++]; if(ch=='=') { syn=22; token[m++]=ch; } else { syn=20; p--; } break; case '>': token[m++]=ch; ch=prog[p++]; if(ch=='=') { syn=24; token[m++]=ch; } else { syn=23; p--; } break; case '+': token[m++]=ch; ch=prog[p++]; if(ch=='+') { syn=17; token[m++]=ch; } else { syn=13; p--; } break; case '-': token[m++]=ch; ch=prog[p++]; if(ch=='-') { syn=29; token[m++]=ch; } else { syn=14; p--; } break; case '!': ch=prog[p++]; if(ch=='=') { syn=21; token[m++]=ch; } else { syn=31; p--; } break; case '=': token[m++]=ch; ch=prog[p++]; if(ch=='=') { syn=25; token[m++]=ch; } else { syn=18; p--; } break; case '*': syn=15; token[m++]=ch; break; case '/': syn=16; token[m++]=ch; break; case '(': syn=27; token[m++]=ch; break; case ')': syn=28; token[m++]=ch; break; case '{': syn=5; token[m++]=ch; break; case '}': syn=6; token[m++]=ch; break; case ';': syn=26; token[m++]=ch; break; case '\"': syn=30; token[m++]=ch; break; case '#': syn=0; token[m++]=ch; break; case ':': syn=17; token[m++]=ch; break; default: syn=-1; break; } } token[m++]='\0'; }
1.3小結:
詞法分析,就是將程式原始碼序列,迴圈讀取一個字串,然後根據詞法要求,確定其屬性,然後組成詞法單元。對於現實中的程式語言,其詞法比較複雜,一般用正則表示式表示。