1、實驗目的及要求
1.1、實驗目的
????????加深對詞法分析器的工作過程的理解;加強對詞法分析方法的掌握;能夠采用一種編程語言實現(xiàn)簡單的詞法分析程序;能夠使用自己編寫的分析程序?qū)唵蔚某绦蚨芜M行詞法分析。
1.2、實驗要求
? ? ? ? 1)對單詞的構詞規(guī)則有明確的定義;
? ? ? ? 2)編寫的分析程序能夠正確識別源程序中的單詞符號;
? ? ? ? 3)識別出的單詞以<種別碼,值>的形式保存在符號表中,正確設計和維護符號表;
? ? ? ? 4)對于源程序中的詞法錯誤,能夠做出簡單的錯誤處理,給出簡單的錯誤提示,保證順利完成整個源程序的詞法分析;
2、實驗步驟
2.1、詞法分析規(guī)則
????????<標識符>::=<字母>|<標識符><字母>|<標識符><數(shù)字>
????????<常數(shù)>::=<數(shù)字>|<數(shù)字序列><數(shù)字>
????????<數(shù)字序列>::=<數(shù)字序列><數(shù)字>|<數(shù)字>|<.>
????????<字母>::=a|b|c|……|x|y|z
????????<數(shù)字>::=0|1|2|3|4|5|6|7|8|9
????????<運算符>::=<關系運算符>|<算術運算符>|<邏輯運算符>|<位運算符>|<賦值運算符>
????????<算數(shù)運算符>::=+|-|*|/|...|--
????????<關系運算符>::=<|>|!=|>=|<=|==
????????<邏輯運算符>::=&&| || |!
????????<位運算符>::=&| | |!
????????<賦值運算符>::==|+=|-=|/=|*=
????????<分界符>::=,|;|(|)|{|}|:| // |/**/
????????<保留字>::=main|if|else|while|do|for|...|void
2.2、單詞符號的編碼
單詞符號 |
種別碼 |
單詞符號 |
種別碼 |
main |
0 |
> |
26 |
if |
1 |
>= |
27 |
else |
2 |
< |
28 |
while |
3 |
<= |
29 |
do |
4 |
! |
30 |
for |
5 |
!= |
31 |
switch |
6 |
= |
32 |
case |
7 |
== |
33 |
int |
8 |
( |
34 |
double |
9 |
) |
35 |
float |
10 |
{ |
36 |
long |
11 |
} |
37 |
void |
12 |
; |
38 |
+ |
13 |
: |
39 |
+= |
14 |
| |
40 |
++ |
15 |
|| |
41 |
- |
16 |
數(shù)字 |
42 |
-= |
17 |
標識符 |
43 |
-- |
18 |
, |
44 |
& |
19 |
// |
45 |
&& |
20 |
/**/ |
46 |
# |
21 |
||
* |
22 |
||
*= |
23 |
||
/ |
24 |
||
/= |
25 |
2.3、狀態(tài)轉(zhuǎn)換圖
2.4、算法分析
????????①詞法分析器工作的第一步是輸入源程序文本。為了更好地對單詞符號識別,把輸入串預處理一下。預處理主要濾掉空格,跳過注釋、換行符等。
????????②對預處理后的輸入串依次掃描單個字符,使用if-while嵌套語句和switch case語句判斷字符的類型,具體識別方法可看狀態(tài)轉(zhuǎn)換圖。有時為了確定詞性,需要超前掃描,若超前掃描的字符對識別當前單詞無用處,則需要退還給輸入串,以備識別下一單詞字符時使用。
????????③若讀入的字符與單詞符號編碼表的字符匹配不上,則報錯,并輸出出錯行數(shù)。對識別處的單詞符號以(單詞符號,種別碼)二元式的形式輸出。
3、實驗內(nèi)容
3.1、流程圖
3.2、程序的變量與函數(shù)說明
- input:全局字符數(shù)組,用來存放輸入串
- word:全局字符數(shù)組,用來存放獲取到的單詞符號,限定長度為8
- ch:全局字符變量,用來存放最新讀入的字符
- syn:全局整型變量,表示單詞符號的編碼
- p:全局整型變量,表示當前字符在input數(shù)組的位置
- m:全局整型變量,表示最新讀入的字符在word數(shù)組的下標
- line:全局整型變量,當前行數(shù)
- keyword:全局字符數(shù)組,存放關鍵字
- init():獲取輸入串
- isKey():判斷關鍵字的函數(shù),若參數(shù)數(shù)組中是關鍵字,則把syn置為該關鍵字對應的編碼并返回1,否則返回0
- isLetter():判斷字母的函數(shù),若參數(shù)字符是字母,則返回1,否則返回0
- isDigit():判斷數(shù)字的函數(shù),若參數(shù)字符是數(shù)字,則返回1,否則返回0
- isSpace():判斷空白符的函數(shù),若參數(shù)字符是空格、TAB或換行符,則返回1,否則返回0
- scaner():掃描輸入串的函數(shù),對讀出的字符進行判斷,若是單詞符號表中的符號,則將syn置為對應的編碼
3.3、源代碼
#include <stdio.h>
#include <string.h>
char input[1000];//輸入串
char word[8];//獲取到的單詞
char ch;
int syn;//種別碼
int p;
int m;
int line;//行數(shù)
//關鍵字
char keyword[][8]={"main","if","else","while","do","for","switch","case","int","double","float","long","void"};
void scaner(void);
//獲取輸入串
void init()
{
int i=0;
printf("\n please input a string(end with '#'):\n");
do{
scanf("%c",&ch);
input[i++]=ch;
}while(ch!='#');
}
//判斷是不是關鍵字
int isKey(char *str)
{
int n;
for(n=0;n<13;n++)
{
if(strcmp(str,keyword[n])==0)
{
syn=n;
return 1;
}
}
return 0;
}
//判斷是不是數(shù)字
int isDigit(char c)
{
if (c>='0'&&c<='9')
return 1;
else
return 0;
}
//判斷是不是字母
int isLetter(char c)
{
if ((c<='z'&&c>='a')||(c>='A'&&c<='Z'))
return 1;
else
return 0;
}
int isSpace(char c)
{
if (c==' '||c=='\t'||c=='\n')
{
return 1;
}
return 0;
}
void main()
{
init();//輸入字符串
line=0;
p=0;
do{
scaner();
switch(syn)
{
case -1:
printf("you have input a wrong string in line %d\n",line);
break;
default:
printf("( %s,%d )\n",word,syn);
break;
}
}while(syn!=21);
}
void scaner(void)
{
//清空word
for(m=0;m<8;m++)
{
word[m] = ' ';
}
//讀取字符
ch=input[p++];
m=0;
//當ch為空格或換行符時,繼續(xù)往下讀
while(isSpace(ch))
{
if (ch=='\n')
{
line++;
}
ch=input[p++];
}
//如果以字母開頭
if(isLetter(ch))
{
//如果往后是字母或數(shù)字,把字符存入word中,然后往下繼續(xù)讀
//串長超過8則截斷
while((isLetter(ch)||isDigit(ch))&&m<8)
{
word[m++]=ch;
ch=input[p++];
}
p--;
syn=43;
word[m++]='\0';
isKey(word);//判斷是不是關鍵字
}
//如果是以數(shù)字開頭,并且往后是數(shù)字
else if(isDigit(ch))
{
while((isDigit(ch)||ch=='.')&&m<8)
{
word[m++]=ch;
ch=input[p++];
}
//如果數(shù)字之后是字母 ,則出錯
if (isLetter(ch))
{
while(!isSpace(ch))
{
ch=input[p++];
}
syn=-1;
return ;
}
p--;
syn=42;
}
else
{
switch(ch)
{
//比較運算符
case '<':
word[m++]=ch;
ch=input[p++];
if(ch=='=')
{
syn=29;
word[m++]=ch;
}
else
{
syn=28;
p--;
}
break;
case '>':
word[m++]=ch;
ch=input[p++];
if(ch=='=')
{
syn=27;
word[m++]=ch;
}
else
{
syn=26;
p--;
}
break;
case '!':
ch=input[p++];
if(ch=='=')
{
syn=31;
word[m++]=ch;
}
else
{
syn=30;
p--;
}
break;
case '=':
word[m++]=ch;
ch=input[p++];
if(ch=='=')
{
syn=33;
word[m++]=ch;
}
else
{
syn=32;
p--;
}
break;
//算術運算符+、-、*、/
case '+':
word[m++]=ch;
ch=input[p++];
if(ch=='+')
{
syn=15;
word[m++]=ch;
}
else if(ch=='=')
{
syn=14;
word[m++]=ch;
}
else
{
syn=13;
p--;
}
break;
case '-':
word[m++]=ch;
ch=input[p++];
if(ch=='-')
{
syn=18;
word[m++]=ch;
}
else if(ch=='=')
{
syn=17;
word[m++]=ch;
}
else if (isDigit(ch))
{
while(isDigit(ch))
{
word[m++]=ch;
ch=input[p++];
}
p--;
syn=42;
}
else
{
syn=16;
p--;
}
break;
case '*':
word[m++]=ch;
ch=input[p++];
if(ch=='=')
{
syn=23;
word[m++]=ch;
}
else
{
syn=22;
p--;
}
break;
case '/':
word[m++]=ch;
ch=input[p++];
if(ch=='=')
{
syn=25;
word[m++]=ch;
}
//如果是單行注釋,則讀到換行符為止
else if (ch=='/')
{
word[m++]=ch;
syn=45;
while (ch!='\n')
{
ch=input[p++];
}
line++;
}
//如果是多行注釋,則讀到匹配的*/為止
else if(ch=='*')
{
word[m++]=ch;
syn=46;
int flag=1;
while (flag)
{
ch=input[p++];
if (ch=='*')
{
if (input[p++]=='/')
{
word[m++]='*';
word[m++]='/';
flag=0;
}
else
{
p--;
}
}
if (ch=='\n')
{
line++;
}
}
}
else
{
syn=24;
p--;
}
break;
//界符
case '(':
syn=34;
word[m++]=ch;
break;
case ')':
syn=35;
word[m++]=ch;
break;
case '{':
syn=36;
word[m++]=ch;
break;
case '}':
syn=37;
word[m++]=ch;
break;
case ';':
syn=38;
word[m++]=ch;
break;
case '#':
syn=21;
word[m++]=ch;
break;
case ':':
syn=39;
word[m++]=ch;
break;
case ',':
syn=44;
word[m++]=ch;
break;
//邏輯運算符
case '&':
word[m++]=ch;
ch=input[p++];
if(ch=='&')
{
syn=20;
word[m++]=ch;
}
else
{
syn=19;
p--;
}
break;
case '|':
word[m++]=ch;
ch=input[p++];
if(ch=='|')
{
syn=41;
word[m++]=ch;
}
else
{
syn=40;
p--;
}
break;
default:
syn=-1;
break;
}
}
//字符串結(jié)束符
word[m++]='\0';
}
4、實驗結(jié)果
因為printf和""不是單詞符號表中的符號,因而判定輸入有錯
?
?文章來源:http://www.zghlxwxcb.cn/news/detail-646746.html
?完整實驗報告:詞法分析器的設計與實現(xiàn)-C文檔類資源-CSDN文庫文章來源地址http://www.zghlxwxcb.cn/news/detail-646746.html
到了這里,關于詞法分析器的設計與實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!