《编译原理》实验1--词法分析程序

一、上机编写一个词法分析程序

     (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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值