一、上机编写一个词法分析程序
(1)单词符号及其分类码
(2)状态转换图见课本P80
(3)要求对于样例1的代码段按照(CLASS,VALUE)的二元式编码输出
2.词法分析程序的输入(input.txt)
begin
%##
if 2ab > b then
c = a
else
c = 100
end
3.词法分析程序的输出
(1,'')(3,’’)(12,'')(6,'b')(4,'')(6,'c')(10,'')(6,'a')(5,'')(6,'c')(10,'')(7,'100')(2,'')
新建autoMachine.c,读取输入文件input.txt,对其中每个字符进行扫描,并且将不符合词法的错误,输出到error_log.txt。
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#define ID 6
#define INT 7
#define LT 8
#define LE 9
#define EQ 10
#define NE 11
#define GT 12
#define GE 13
char TOKEN[20];
extern int lookup(char*);
extern void out(int, char*);
extern report_error(int,FILE*);
void scanner_test(FILE* fp,FILE* log_fp);
int main() {
FILE* fp = fopen("input.txt", "r");
if (fp == NULL) {
perror("Error opening file");
return 1;
}
// 打开日志文件
FILE* log_fp = fopen("error_log.txt", "w");
if (log_fp == NULL) {
perror("Error opening log file");
fclose(fp);
return 1;
}
scanner_test(fp,log_fp);
fclose(fp);
fclose(log_fp);
return 0;
}
void scanner_test(FILE* fp,FILE* log_fp) {
char ch;
int line = 1;
while ((ch=fgetc(fp)) != EOF) {
int i, c;
if (ch == '\n') {
line++;
continue;
}
if (isspace(ch)) {
continue;
}
if (isalpha(ch)) {
TOKEN[0] = ch;
ch = fgetc(fp);
i = 1;
while (isalnum(ch)) {
TOKEN[i] = ch;
i++;
ch = fgetc(fp);
}
TOKEN[i] = '\0';
fseek(fp, -1, 1);
c = lookup(TOKEN);
if (c == 0)
out(ID, TOKEN);
else
out(c, " ");
}
else {
if (isdigit(ch)) {
TOKEN[0] = ch;
ch = fgetc(fp);
i = 1;
while (isdigit(ch)) {
TOKEN[i] = ch;
i++;
ch = fgetc(fp);
}
TOKEN[i] = '\0';
if (ch != '\n' && ch != ' ') {
while (ch != '\n' && ch != ' ') {
ch = fgetc(fp);
}
report_error(line, log_fp);
}
else {
out(INT, TOKEN);
}
fseek(fp, -1, 1);
}
else {
switch (ch) {
case '<':ch = fgetc(fp);
if (ch == '=')
out(LE, " ");
else if (ch == '>')
out(NE, " ");
else {
fseek(fp, -1, 1);
out(LT, " ");
}
break;
case '=':
out(EQ, " ");
break;
case '>':
ch = fgetc(fp);
if (ch == '=')
out(GE, " ");
else {
fseek(fp, -1, 1);
out(GT, " ");
}
break;
default:
report_error(line,log_fp);
break;
}
}
}
}
return;
}
新建function.c,实现lookup、 out 以及report_error方法
#include<stdio.h>
#include<string.h>
char* KEYWORDS[6] = { "begin","end","if","then","else" };
int lookup(char* word) {
for (int i = 0; i < 5; i++) {
if (strcmp(word, KEYWORDS[i])==0) {
return i+1;
}
}
return 0;
}
void out(int n, char* word) {
printf("(%d,'%s')", n, word);
}
report_error(int line,FILE* fp) {
fprintf(fp, "第%d行出错,无效的输入值.\n", line);
}