【编译原理课程设计】词法分析程序设计
【实验目的】
(1)理解词法分析在编译程序中的作用
(2)加深对有穷自动机模型的理解
(3)掌握词法分析程序的实现方法和技术
【实验内容】
对一个简单语言的子集编制一个一遍扫描的词法分析程序。
【实验要求】
(1)待分析的简单语言的词法
1) 关键字
begin if then while do end
2) 运算符和界符
:= + - * / < <= > >= <> = ; ( ) #
3) 其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义:
ID=letter(letter|digit)*
NUM=digitdigit*
4) 空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。
(2)各种单词符号对应的种别编码
单词符号 |
种别码 |
单词符号 |
种别码 |
begin |
1 |
: |
17 |
if |
2 |
:= |
18 |
then |
3 |
< |
20 |
while |
4 |
<> |
21 |
do |
5 |
<= |
22 |
end |
6 |
> |
23 |
letter(letter|digit)* |
10 |
>= |
24 |
digitdigit* |
11 |
= |
25 |
+ |
13 |
; |
26 |
- |
14 |
( |
27 |
* |
15 |
) |
28 |
/ |
16 |
# |
0 |
(3)词法分析程序的功能
输入:所给文法的源程序字符串
输出:二元组(syn,token或sum)构成的序列。
syn为单词种别码;
token为存放的单词自身字符串;
Sum 为整形常数。
例如:对源程序begin x:=9;if x>0 then x:=2*x+1/3;end# 经词法分析后输出如下序列:(1,begin)(10,’x’) (18,:=) (11,9) (26,;) (2,if)……
直接上代码
1 #include<iostream> 2 using namespace std; 3 bool is_digit(char ch); 4 bool is_letter(char ch); 5 char example[10000]; //缓冲区 6 char token[10]; //标识符 7 int syn, sum; 8 const char* keyword[10] = { "begin","if","then","while","do","end" }; //关键字 9 int example_p;//缓冲区指针 10 int token_p;//标识符指针 11 char ch; 12 13 //扫描 14 void scan() { 15 16 memset(token, 0, sizeof(token)); //数组清零 17 token_p = 0; 18 while (ch ==' ') { 19 example_p++; 20 ch = example[example_p]; 21 } 22 23 //字符是数字 24 if (is_digit(ch)) { 25 sum = 0; 26 //检索数字 27 while (is_digit(ch)) { 28 //得到结果 29 sum = sum * 10 + ch - '0'; //将字符转换成数字 30 example_p++; 31 ch = example[example_p]; 32 syn = 11; 33 } 34 35 } 36 //字符是字母 37 else if (is_letter(ch)) { 38 //检索标识符、关键字 39 while (is_digit(ch) || is_letter(ch)) { 40 token[token_p] = ch; 41 token_p++; 42 example_p++; 43 ch = example[example_p]; 44 } 45 46 47 token[token_p] = '\0'; 48 token_p++; 49 syn = 10; 50 //比对标识符和关键字 51 for (int i = 0;i < 6;i++) { 52 if (strcmp(token, keyword[i]) == 0) { 53 syn = i + 1; 54 break; 55 } 56 } 57 } 58 //其他情况 59 else { 60 switch (ch){ 61 case '#': 62 syn = 0; 63 token[0] = ch; 64 break; 65 case '+': 66 syn = 13; 67 token[0] = ch; 68 example_p++; 69 ch = example[example_p]; 70 break; 71 case '-': 72 syn = 14; 73 token[0] = ch; 74 example_p++; 75 ch = example[example_p]; 76 break; 77 case '*': 78 syn = 15; 79 token[0] = ch; 80 example_p++; 81 ch = example[example_p]; 82 break; 83 case '/': 84 syn = 16; 85 token[0] = ch; 86 example_p++; 87 ch = example[example_p]; 88 break; 89 90 case ':': 91 syn = 17; 92 token_p = 0; 93 token[token_p] = ch; 94 token_p++; 95 example_p++; 96 ch = example[example_p]; 97 if (ch == '=') { 98 token[token_p] = ch; 99 token_p++; 100 syn = 18; 101 example_p++; 102 ch = example[example_p]; 103 } 104 break; 105 106 case '<': 107 syn = 20; 108 token_p = 0; 109 token[token_p] = ch; 110 token_p++; 111 example_p++; 112 ch = example[example_p]; 113 if (ch == '>') { 114 token[token_p] = ch; 115 token_p++; 116 syn = 21; 117 example_p++; 118 ch = example[example_p]; 119 } 120 if (ch == '=') { 121 token[token_p] = ch; 122 token_p++; 123 syn = 22; 124 example_p++; 125 ch = example[example_p]; 126 } 127 break; 128 case '>': 129 syn = 23; 130 token_p = 0; 131 token[token_p] = ch; 132 token_p++; 133 example_p++; 134 ch = example[example_p]; 135 if (ch == '=') { 136 token[token_p] = ch; 137 token_p++; 138 syn = 24; 139 example_p++; 140 ch = example[example_p]; 141 } 142 break; 143 case '=': 144 syn = 25; 145 token[0] = ch; 146 example_p++; 147 ch = example[example_p]; 148 break; 149 case ';': 150 syn = 26; 151 token[0] = ch; 152 example_p++; 153 ch = example[example_p]; 154 break; 155 case '(': 156 syn = 27; 157 token[0] = ch; 158 example_p++; 159 ch = example[example_p]; 160 break; 161 case ')': 162 syn = 28; 163 token[0] = ch; 164 example_p++; 165 ch = example[example_p]; 166 break; 167 168 } 169 170 } 171 172 173 174 } 175 //字符是数字 176 bool is_digit(char ch) { 177 if (ch >= '0'&&ch <= '9') 178 return true; 179 else 180 return false; 181 } 182 //字符是字母 183 bool is_letter(char ch) { 184 if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) 185 return true; 186 else 187 return false; 188 } 189 int main() { 190 example_p = 0; 191 char str; 192 do { 193 str = getchar(); 194 example[example_p] = str; 195 example_p++; 196 } while (str != '#'); 197 198 example_p = 0; 199 ch = example[example_p]; 200 201 202 do { 203 scan(); 204 switch (syn) { 205 case 11: 206 cout <<"("<< syn << "," << sum <<")"<< endl; 207 break; 208 default: 209 cout <<"("<< syn << "," << token<<")"<<endl; 210 } 211 } while (syn != 0); 212 213 214 system("pause"); 215 216 return 0; 217 }