Lex编程初学者求助:q1.l第12行出现“未识别规则”错误
Lex报错"unrecognized rule"问题解决
问题描述
我是Lex编程的初学者,目前遇到报错:“q1.l”,line 12: unrecognized rule。以下是我的代码:
%{ #include<stdio.h> int count=0; %} op [+-*/] letter [a-zA-Z] digitt [0-9] id {letter}*|({letter}{digitt})+ notid ({digitt}{letter})+ %% [ ]+ ("int")|("float")|("char")|("case")|("default")| ("if")|("for")|("printf")|("scanf") {printf("%s is a keyword ", yytext);} {id} {printf("%s is an identifier ", yytext); count++;} {notid} {printf("%s is not an identifier ", yytext);} %% int main() { FILE *fp; char file[10]; fp=fopen(input,"r"); yyin=fp; yylex(); printf("Total identifiers are: %d ", count); return 0; }
错误原因及修正方案
1. 空白字符规则写法错误
第12行的[ ]+是非法格式,Lex无法识别包含不可见换行的字符集定义。正确的空白字符匹配规则应明确指定匹配空格、制表符和换行:
[ \t\n]+ /* 匹配并忽略空白字符 */
2. 关键词规则语法错误
- 无需给每个关键词单独加括号,直接用
|分隔即可; - 规则中
|后的空格会被当作匹配内容的一部分,导致关键词匹配失败,必须删除多余空格; - printf语句中的换行需用
\n表示,不能直接换行。
修正后的关键词规则:
"int"|"float"|"char"|"case"|"default"|"if"|"for"|"printf"|"scanf" {printf("%s is a keyword\n", yytext);}
3. 标识符正则定义不合理
原id {letter}*|({letter}{digitt})+会匹配空字符串,不符合“标识符以字母开头,后续可跟字母/数字”的标准定义,修正为:
id {letter}({letter}|{digitt})*
4. 文件打开逻辑错误
fopen(input,"r")中的input未定义,需先读取用户输入的文件名再打开文件,同时增加文件打开失败的异常判断:
printf("Enter filename: "); scanf("%s", file); fp = fopen(file, "r"); if(fp == NULL){ perror("Failed to open file"); return 1; }
完整修正代码
%{ #include<stdio.h> int count=0; %} op [+-*/] letter [a-zA-Z] digitt [0-9] id {letter}({letter}|{digitt})* notid ({digitt}{letter})+ %% [ \t\n]+ /* 忽略空白字符 */ "int"|"float"|"char"|"case"|"default"|"if"|"for"|"printf"|"scanf" {printf("%s is a keyword\n", yytext);} {id} {printf("%s is an identifier\n", yytext); count++;} {notid} {printf("%s is not an identifier\n", yytext);} %% int main() { FILE *fp; char file[10]; printf("Enter filename: "); scanf("%s", file); fp = fopen(file, "r"); if(fp == NULL){ perror("Failed to open file"); return 1; } yyin = fp; yylex(); printf("Total identifiers are: %d\n", count); fclose(fp); return 0; }
内容的提问来源于stack exchange,提问作者Vishal Kumar
相关产品推荐
相关产品推荐

