近日学习编译原理,用C写了一个词法分析器,但编译提示
two or more data types in declaration of `col’ 的错误,请各位帮忙看看
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define false 0
#define true 1
#define WORDLEN 20
/*单词编码表*/
const char *table[] = {“if”,”then”,”else”,”endif”,”while”,”do”,”enddo”,”var”,”int” ,”real”,”void”, “+”,”-”,”*”,”/”,”%”,”++”,”–”,”=”,”<”,”<=”,”>”,”=”, “=”,”=”,”!”,”&”,”|”,”,”,”;”,”(“,”)”,”#”};
const char code[] = {“jtefwdrvacn+-*/%$@=<[>]^~!&|,;()#”};
/*DFA字符序列*/
char COL_CHAR[] = “a0+-*/%=<>!&|,;()#”;
/*状态转换矩阵 (DFA) */
const int DFA[][19] = {
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,0},
{19,19},
{0,20},
{0,0,21},
{0,0,0,22},
{0},
{0},
{0},
{0,0,0,0,0,0,0,23},
{0,0,0,0,0,0,0,0,24},
{0,0,0,0,0,0,0,0,0,25},
{0,0,0,0,0,0,0,0,0,0,26},
{0},
{0},
{0},
{0},
{0},
{0},
{0},
{19,19},
{0,20},
{0},
{0},
{0},
{0},
{0},
{0}
};
struct code_val{
char code;
char val[WORDLEN];
}
int col(char); /*列定位函数原型*/
void concat(char[],char); /*拼接函数原型*/
char search_table(char[]); /*查单词二元式编码表函数原型*/
/*扫描器的控制程序*/
struct code_val scanner(char *buf)
{
static int i = 0; /*静态局部变量,扫描缓冲区指示器*/
struct code_val t = {‘\0′,”NUL”}; /*存放单词二元式,识别前清空*/
char token[WORDLEN] = “”; /*用于拼接单词,识别前清空*/
/*去除前导空格*/
while(buf == ‘ ‘) i++;
/*从初态出发识别单词*/
int cur_state = 0;
while(DFA[cur_state][col(buf)]) { /*存在后继状态*/
concat(token,buf); /*拼接*/
cur_state = DFA[cur_state][col(buf)];/*进入下一状态*/
if(buf[++i] == ‘\0′) break; /*缓冲区内字符是否处理完*/
}
t.code = search_table(token); /*查单词二元式*/
if(t.code == ‘?’) {
if(token[0] >= ‘a’ && token[0] <= ‘z’)/*是标识符*/
t.code = ‘i’;
else /*否则是整常数*/
t.code = ‘x’;
strcpy(t.val,token);
}
return t; /*返回当前单词的二元式*/
}
/*列定位函数*/
int col(char c)
{
int i;
if(c >= ‘a’ && c <= ‘z’) c = ‘a’;
if(c >= ’0′ && c <= ’9′) c = ’0′;
for(i = 0; i < strlen(COL_CHAR); i++)
{
if(c == COL_CHAR) return i;
else printf(“Error char %c\n”, c);
exit(0);
}
}
char search_table(char token[]) /*根据token内容查单词二元式编码表,返回单词种别*/
{
int i;
for(i = 0; i < strlen(code); i++)
if(strcmp(token,table) == 0) return code;
else return ‘?’; /*’?'表示查表无果*/
}
void concat(char token[], char c)
{
int i;
for(i = 0; token; i++); /*找到尾*/
token = c;
token[++i] = ‘\0′;
}
/*预处理程序*/
void call(char *buf)
{
int i = 0; /*计数器*/
FILE *fp;
if((fp = fopen(“source.txt”,”r”)) == NULL)
{
printf(“Can’t open the file.\n”);
exit(0);
}
char old_c = ‘\0′,cur_c; /*前一个字符,当前字符*/
int in_comment = false; /*false表示当前字符未处于注释中*/
while((cur_c = getc(fp)) != EOF)
{
switch(in_comment)
{
case false:
if(old_c == ‘/’ && cur_c == ‘*’) /*进入注释*/
{
i–; /*去除已存入扫描缓冲区的字符’/'*/
in_comment = true;
}
else
{
if(old_c == ‘\\’ && cur_c == ‘\n’) /*发现续行*/
i–; /*去除已存入扫描缓冲区的字符’\'*/
else
{
if(cur_c >= ‘A’ && cur_c <= ‘Z’) /*大写变小写*/
cur_c += 32;
if(cur_c == ‘\t’ || cur_c == ‘\n’) /*空格取代Tab换行*/
cur_c = ‘ ‘;
buf[i++] = cur_c;
}
}
break;
case true:
if(old_c == ‘*’ && cur_c == ‘/’) /*离开注释*/
in_comment = false;
}
old_c = cur_c; /*在源程序尾部添加字符’#'*/
}
buf[i++] = ‘#’;
fclose(fp);
}
int main()
{
int i;
char buf[4048] = {‘\0′}; /*扫描缓冲区*/
call(buf); /*预处理*/
FILE *fp;
if((fp = fopen(“Lex_r.txt”,”w”)) == NULL)
{
printf(“Can’t open the file.\n”);
exit(0);
}
struct code_val t;
do {
t = scanner(buf);
putc(t.code,fp);
putc(‘\n’,fp);
}while(t.code != ‘#’);
printf(“End of lexicalanalysis!\n”);
fclose(fp);
}
>> 本文固定链接: http://www.vcgood.com/archives/1136
>> 转载请注明: antique008 2006年10月06日 于 C语言帝国 发表
定义了两个col函数