简单词法分析器c语言程序,C语言简单词法分析器

/*

词法分析器(C语言)

输入源程序、输出单词符号

一、预处理程序

二、扫描器(单词识别程序)

*/

#include

#include

#include

#define KEYWORD_NUM 32

int pos;// pos搜索指针

char ch;// ch最新读入的字符

char buf[1000000];// buf缓冲区

char strToken[256];// strToken

char* key_word[] = {"auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else",

"enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed",

"sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while"};

/*

预处理主要工做:

一、删除注释

二、删除续行符,以及后续换行符(0AH)。

三、换行符、TAB和空格具备界符做用,预处理时一般予以保留。为了简化判断,可在预处理时,将换行符和TAB统一替换为空格。

四、大多数语言(除C语言)不区分大小写,可在预处理时,将大写字母变换成小写字母,或相反,以方便后续处理。

五、对于受书写格式限制的语言(例Fortran和Cobol),还应识别标号区,正确给出语句标号。识别续行标志,把相继行捻接在一块儿,给出语句结束符。

*/

void pre_process(char* filename) {//扫描缓冲区buf[ ]和扫描缓冲区指针i

FILE *fp;

if ((fp = fopen(filename, "r")) == NULL) {

printf("file %s read error!\n", filename);

exit(0);

}

char old_c = '\0', cur_c;

int in_comment = 0;// in_comment是否在注释内,1为在单行注释中,2为在多行注释中,或者拆分in_scomment、inmcomment

int in_string = 0;// in_string是否在字符串常量内

int i = 0;

while ((cur_c = fgetc(fp)) != EOF) {// 文件还没有处理完

//printf("cur_c = %c\n", cur_c);

if (in_string) {// 当前字符在字符串常量中

if (old_c != '\\' && cur_c == '"') {// 判断"前是不是转义字符

in_string = 0;

}

buf[i] = cur_c;//送入扫描缓冲区

i++;

} else {

if (!in_comment) { //当前字符未处于注释中

if (old_c == '/' && cur_c == '/') {// 单行注释

i = i - 1;

in_comment = 1;

} else if (old_c == '/' && cur_c == '*') {// 多行注释

i = i - 1;

in_comment = 2;

} else {// 不在注释内

if (old_c == '\\' && cur_c == '\n') {// 续行符

i = i - 1;

} else if (cur_c == '\t' || cur_c == '\n') {// 将制表符和换行符统一替换为空格

cur_c = ' ';

}

if (old_c != '\'' && cur_c == '"') in_string = 1;// 字符串常量,须要判断"是不是字符常量

buf[i] = cur_c;//送入扫描缓冲区

i++;

}

//printf("buf[%d] = %c\n", i, cur_c);

} else if (in_comment == 1){//当前字符处于单行注释中

if (cur_c == '\n') in_comment = 0;// 离开注释

} else {// 当前字符处于多行注释中

if (old_c == '*' && cur_c == '/') in_comment = 0;//离开注释

}

}

old_c = cur_c;

}

if (buf[i] != ' ' && buf[i] != '\0'){

i++;

}

buf[i] = '#';

buf[i + 1] = '\0';

printf("预处理后:");

printf("buf:\n", buf);

int j = 0;

char last = '\0';

char now = buf[0];

while (!(last == '#' && now == '\0')) {// #加'\0'为结束

printf("%c", now);

last = now;

now = buf[++j];

}

printf("\nbuf length %d\n", strlen(buf));

fclose(fp);

}

void formatting() {// 将预处理后的代码按某种风格输出

}

void GetChar() {// GetChar 子程序过程,把下一个字符读入到 ch 中

ch = buf[pos++];

//printf("read ch = %c\n", ch);

}

void GetBC() {// GetBC 子程序过程,跳过空白符,直至 ch 中读入一非空白符

while (ch == ' ') GetChar();

}

void Concat(char* strToken) {

int len = strlen(strToken);

strToken[len++] = ch;

strToken[len] = '\0';

}

int IsLetter() {//IsLetter 布尔函数,判断ch中字符是否为字母

if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')

return 1;

else

return 0;

}

int IsDigit() {// IsDigit 布尔函数,判断ch中字符是否为数字

if (ch >= '0' && ch <= '9') return 1;

else return 0;

}

int Reserve(char* strToken) {// Reserve 整型函数,对于 strToken 中的字符串查找保留字表,若它是保留字则给出它的编码,不然回送0

int i;

for (i = 0; i < KEYWORD_NUM; i++) {

if (!strcmp(strToken, key_word[i]))

return i + 1;

}

return 0;

}

void Retract() {// Retract 子程序,把搜索指针回调一个字符位置

pos--;

}

int InsertId(char* strToken) {// InsertId 整型函数,将strToken中的标识符插入符号表,返回符号表指针

return 0;

}

int InsertConst(char* strToken) {// InsertConst 整型函数过程,将strToken中的常数插入常数表,返回常数表指针。

return 0;

}

void ProcError() {

printf("ch = \'%c\', Error!", ch);

exit(0);

}

void scanner() {

/*

1)ch 字符变量、存放最新读入的源程序字符

2)strToken 字符数组,存放构成单词符号的字符串

3)GetChar 子程序过程,把下一个字符读入到 ch 中

4)GetBC 子程序过程,跳过空白符,直至 ch 中读入一非空白符

5)Concat 子程序,把ch中的字符链接到 strToken

6)IsLetter和 IsDisgital 布尔函数,判断ch中字符是否为字母和数字

7) Reserve 整型函数,对于 strToken 中的字符串查找保留字表,若它实保留字则给出它的编码,不然回送0

8) Retract 子程序,把搜索指针回调一个字符位置

9)InsertId 整型函数,将strToken中的标识符插入符号表,返回符号表指针

10)InsertConst 整型函数过程,将strToken中的常数插入常数表,返回常数表指针。

*/

printf("\n单词符号:\n");

int code, value;

pos = 0;

ch = ' ';

while (1) {

strcpy(strToken, "");// 置strToken为空串

GetChar();

GetBC();

if (IsLetter() || ch == '_') {// 变量

while (IsLetter() || IsDigit() || ch == '_') {

Concat(strToken);

GetChar();

}

Retract();

code = Reserve(strToken);

if (code == 0) {

value = InsertId(strToken);

printf("(\'id\', %s)\n", strToken);

} else printf("(%s, -)\n", strToken);

} else if (IsDigit()) {// 数,须要完善

while (IsDigit() || ch == '.' || ch == 'e' || ch == 'E') {

Concat(strToken);

GetChar();

}

Retract();

value = InsertConst(strToken);

printf("(\'int\', %s)\n", strToken);

} else if (ch == '"'){// 字符串

Concat(strToken);

GetChar();

int p = 0;// p标记转义字符

while (!(p == 0 && ch == '"')) {

if (p) {

p--;

} else {

if (ch == '\\') p = 1;

}

Concat(strToken);

GetChar();

}

Concat(strToken);

printf("(\'string\', %s)\n", strToken);

} else if (ch == '=') {

GetChar();

if (ch == '=') printf("(\'==\', -)\n");

else {

Retract();

printf("(\'=\', -)\n");

}

} else if (ch == '+') {

GetChar();

if (ch == '=') printf("(\'+=\', -)\n");

else {

Retract();

printf("(\'+\', -)\n");

}

} else if (ch == '-') {

GetChar();

if (ch == '=') printf("(\'-=\', -)\n");

else {

Retract();

printf("(\'-\', -)\n");

}

} else if (ch == '*') {

GetChar();

if (ch == '=') printf("(\'*=\', -)\n");

else {

Retract();

printf("(\'*\', -)\n");

}

} else if (ch == '/') {

GetChar();

if (ch == '=') printf("(\'/=\', -)\n");

else {

Retract();

printf("(\'/\', -)\n");

}

} else if (ch == '|') {

GetChar();

if (ch == '|') printf("(\'||\', -)\n");

else if (ch == '=') printf("(\'|=\', -)\n");

else {

Retract();

printf("(\'|\', -)\n");

}

}

else if (ch == '\\') printf("(\'\\\', -)\n");

else if (ch == ';') printf("(\';\', -)\n");

else if (ch == '(') printf("(\'(\', -)\n");

else if (ch == ')') printf("(\')\', -)\n");

else if (ch == '

GetChar();

if (ch == '=') printf("(\'<=\', -)\n");

else {

Retract();

printf("(\'

}

} else if (ch == '>') {

GetChar();

if (ch == '=') printf("(\'>=\', -)\n");

else {

Retract();

printf("(\'>\', -)\n");

}

} else if (ch == '{') printf("(\'{\', -)\n");

else if (ch == '}') printf("(\'}\', -)\n");

else if (ch == '[') printf("(\'[\', -)\n");

else if (ch == ']') printf("(\']\', -)\n");

else if (ch == '.') printf("(\'.\', -)\n");

else if (ch == '#') {

GetChar();

if (ch == '\0') break;// 退出扫描

Retract();

printf("(\'#\', -)\n");

} else if (ch == '?') printf("(\'#\', -)\n");

else if (ch == ',') printf("(\',\', -)\n");

else if (ch == ':') printf("(\':\', -)\n");

else if (ch == '\'') {// 字符

Concat(strToken);

GetChar();

int p = 0;// 标记转义字符

while (!(p == 0 && ch == '\'')) {

Concat(strToken);

if (p) {

p--;

} else {

if (ch == '\\') p = 1;

}

GetChar();

}

Concat(strToken);

printf("(\'char\', %s)\n", strToken);

} else if (ch == '!') {

GetChar();

if (ch == '=') printf("(\'!=\', -)\n");

else {

Retract();

printf("(\'!\', -)\n");

}

} else if (ch == '&') {

GetChar();

if (ch == '&') printf("(\'&&\', -)\n");

else {

Retract();

printf("(\'&\', -)\n");

}

}

else ProcError();//错误处理

}

}

void test() {// 测试

printf("test:\", \"/*hfuehfu*/, //dwubfuq/*\n");// 测试字符串常量

double sum = (4 + 1.8 / 0.9) * 2.3 - 12.1e1;// 测试数

printf("%.3lf\n", sum >= 0 ? sum : 0);

}

int main() {

char* filename = "source.txt";

//printf("please input file name:\n");

//gets(filename);

pre_process(filename);

scanner();

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值