1 /*main.c XL分析器 */
2
3 main()
4 {
5 statements();
6 }
1 /*lex.c XL分析器 */
2
3
4 #include "lex.h"
5 #include <stdio.h>
6 #include <ctype.h>
7
8 char *yytext = ""; /* 当前词形,注意由于是直接指向
9 行缓冲区input_buffer,因此不是以'\0'结尾,
10 因此使用时要小心, 设初值为0, 表示缓冲区为空,
11 需要重新读行 */
12 int yyleng = 0; /* 词形的长度 */
13 int yylineno = 0; /* 输入的行号 */
14
15 lex()
16 {
17 static char input_buffer[128];
18 char *current;
19
20 current = yytext + yyleng; /* 跳过以读过的词形 */
21
22 while (1) { /* 读下一个词形 */
23 while (!*current) {
24 /* 如果当前缓冲区已读完,重新从键盘读入新的一行.
25 并且跳过空格
26 */
27
28 current = input_buffer;
29 /* 如果读行有误,返回 EOI */
30 if (!fgets(input_buffer, 127, stdin)) {
31 *current = '\0';
32 return EOI;
33 }
34
35 ++yylineno;
36
37 while (isspace(*current))
38 ++current;
39 }
40
41 for (; *current; ++current) {
42 /* Get the next token */
43
44 yytext = current;
45 yyleng = 1;
46
47 /* 返回不同的词汇代码 */
48 switch (*current) {
49 case ';': return SEMI;
50 case '+': return PLUS;
51 case '-': return MINUS;
52 case '/': return DIVISION;
53 case '*': return TIMES;
54 case '(': return LP;
55 case ')': return RP;
56
57 case '\n':
58 case '\t':
59 case ' ': break;
60
61 default:
62 if (!isalnum(*current))
63 fprintf(stderr, "Ignoring illegal input <%c>\n", *current);
64 else {
65 while (isalnum(*current))
66 ++current;
67
68 yyleng = current - yytext;
69 return NUM_OR_ID;
70 }
71
72 break;
73 }
74 }
75 }
76 }
77
78 static int Lookahead = -1; /* 向前查看的词汇,设初值为-1
79 表示第一次调用match函数时
80 必须要读取一个词汇 */
81
82 int match(int token)
83 {
84 /* 判断token是否和当前向前查看的词汇相同. */
85
86 if (Lookahead == -1)
87 Lookahead = lex();
88
89 return token == Lookahead;
90 }
91
92 void advance()
93 {
94 /* 向前都一个词汇 */
95 Lookahead = lex();
96 }
1 /* lex.h XL分析器*/
2 #define EOI 0 /* end of input */
3 #define SEMI 1 /* ; */
4 #define PLUS 2 /* + */
5 #define TIMES 3 /* * */
6 #define LP 4 /* ( */
7 #define RP 5 /* ) */
8 #define NUM_OR_ID 6 /* decimal number or identifier */
9 #define MINUS 7
10 #define D