无法让 flex 识别关键字字符串
can't get flex to recognize keyword strings
我正在尝试使用 flex 为 C 编程语言编写语法荧光笔。我的问题是程序在到达任何关键字模式时停止读取输入并以某种方式卡住。 (关键字定义规则是规则部分中定义的第一个规则)我不知道为什么会这样,关键字的正则表达式似乎很好。
这是代码:
%{
#include <stdio.h>
#include <string.h>
enum token_type{
KEYWORD,
ID,
INTEGER,
FLOAT_NUMBER,
SOME_CHARACTER,
SOME_STRING,
SPECIAL_CHARACTER,
COMMENT,
MULTILINE_COMMENT,
ENDING_DOUBLE_QUOTE
};
int yy_left_integer;
double yy_left_double;
char* yy_left_string;
%}
%x in_multiline_comment
%x in_string
%option noyywrap
%%
"auto"|"int"|"const"|"short"|"break"|"long"|"continue"|"double"|"struct"|"float"|"unsigned"|"else"|"switch"|"for"|"signed"|"case"|"register"|"default"|"sizeof"|"char"|"return"|"do"|"static"|"void"|"enum"|"typedef"|"goto"|"volatile"|"extern"|"union"|"if"|"while" {yy_left_string = yytext; return KEYWORD;}
"/*" BEGIN(in_multiline_comment);
"//"[^ \n]* {yy_left_string = yytext; return COMMENT;}
[a-zA-Z_][a-zA-Z0-9_]* {yy_left_string = yytext; return ID;}
(("0x")[+-]?[0-9A-F]+) | ([+-]?[0-9]+) {yy_left_integer = atoi(yytext); return INTEGER;}
([+-]?[0-9]*\.[0-9]+)(E[+-]?[0-9]+)? {yy_left_double = atof(yytext); return FLOAT_NUMBER;}
\" {BEGIN(in_string);}
<in_string>{
[\.?] {yy_left_string = yytext; return SPECIAL_CHARACTER;}
[^\"\]* {strncpy(yy_left_string, yytext + 1, strlen(yytext -1)); return SOME_STRING;}
\" {yy_left_string = yytext; BEGIN(INITIAL); return ENDING_DOUBLE_QUOTE;}
}
\(.?) {yy_left_string = yytext; return SPECIAL_CHARACTER;}
\'[^ \']?\' {yy_left_string = yytext; return SOME_CHARACTER;}
<in_multiline_comment>{
"*/" {yy_left_string = yytext; BEGIN(INITIAL); return MULTILINE_COMMENT;}
^[*\n]+
"*"
"\n" yylineno++;
}
[\n] {yylineno++;}
[\t\v] {}
. {yy_left_string = yytext;}
%%
int main(int argc, char** argv)
{
int token;
if(argc > 1){
if(!(yyin = fopen(argv[1], "r"))){
perror(argv[1]);
return 1;
}
}
FILE* highlighted_html_file = fopen("highlighted.html", "w");
if(highlighted_html_file == NULL){
printf("error opening file\n");
return 1;
}
while(token = yylex()){
if(token == KEYWORD){fprintf(highlighted_html_file,"<b><span style=\"color:Blue\">%s</span> </b>", yy_left_string);}
else if(token == ID){fprintf(highlighted_html_file,"<span style = \"color:Orange\"> %s </span>", yy_left_string);}
else if(token == INTEGER){fprintf(highlighted_html_file, "<span style = \"color:Purple\"> %d </span>", yy_left_integer);}
else if(token == FLOAT_NUMBER){fprintf(highlighted_html_file, "<i><span style = \"color:Purple\">%f</span></i>", yy_left_double);}
else if(token == SPECIAL_CHARACTER){fprintf(highlighted_html_file, "<span style = \"color:LightBlue\"> \"%s </span>", yy_left_string);}
else if(token == SOME_STRING){fprintf(highlighted_html_file, "<span style = \"color:Red\"> \"%s", yy_left_string);}
else if(token == ENDING_DOUBLE_QUOTE){fprintf(highlighted_html_file, "<span style = \"color:Red>\"</span>");}
else if(token == SOME_CHARACTER){fprintf(highlighted_html_file, "<span style = \"color:LightRed\"> \"%s </span>", yy_left_string);}
else if(token == COMMENT || token == MULTILINE_COMMENT){fprintf(highlighted_html_file, "<span style = \"color:Grey\"> %s</span>", yy_left_string);}
else {fprintf(highlighted_html_file, "%s", yy_left_string);}
}
}
枚举 token_type KEYWORD 的值为 0,如果您的标记为 0,则循环终止。
变化
enum token_type{
KEYWORD,
成为:
enum token_type{
KEYWORD = 1,
这个问题就会消失。
据我所知,您不应该仅使用变量赋值将 "yytext" 复制到您的变量。你应该使用 strdup 或类似的东西复制它。
此外,下面的代码很糟糕:
<in_string>{
[\.?] {yy_left_string = yytext; return SPECIAL_CHARACTER;}
[^\"\]* {strncpy(yy_left_string, yytext + 1, strlen(yytext -1)); return SOME_STRING;}
什么是手段?这意味着如果你处理 \a,那么你将执行 "yy_left_string = yytext"。 IE。现在 yy_left_string 是 "char*" 指向 flex 内部的一些内存。假设您处理普通字符,例如 z。现在你做 "strncpy(yy_left_string,...)"。因此,您将 yy_left_string(即指向某个 flex 内部内存的指针!!!)传递给 strncpy。因此,您将一些数据写入 flex 内部。这可以打破一切。而且您甚至不知道 yy_left_string 是否有足够的 space 来存储所有 yytext 字符。所以,你很容易陷入分段错误。
你了解 C 中的内存是如何工作的吗?你了解指针等吗?你了解 C 中的字符串处理吗?
另外,我不确定我提供的所有关于 yytext 的信息。 IE。我不确定 yytext 是否真的不应该存储在您的变量中。而且我不确定写入 yytext 指向的内存是不是个好主意。阅读 flex 文档以获取所有这些信息。
(另外,你的标签 "flex" 是错误的,因为它是关于其他 flex 的。)
我正在尝试使用 flex 为 C 编程语言编写语法荧光笔。我的问题是程序在到达任何关键字模式时停止读取输入并以某种方式卡住。 (关键字定义规则是规则部分中定义的第一个规则)我不知道为什么会这样,关键字的正则表达式似乎很好。
这是代码:
%{
#include <stdio.h>
#include <string.h>
enum token_type{
KEYWORD,
ID,
INTEGER,
FLOAT_NUMBER,
SOME_CHARACTER,
SOME_STRING,
SPECIAL_CHARACTER,
COMMENT,
MULTILINE_COMMENT,
ENDING_DOUBLE_QUOTE
};
int yy_left_integer;
double yy_left_double;
char* yy_left_string;
%}
%x in_multiline_comment
%x in_string
%option noyywrap
%%
"auto"|"int"|"const"|"short"|"break"|"long"|"continue"|"double"|"struct"|"float"|"unsigned"|"else"|"switch"|"for"|"signed"|"case"|"register"|"default"|"sizeof"|"char"|"return"|"do"|"static"|"void"|"enum"|"typedef"|"goto"|"volatile"|"extern"|"union"|"if"|"while" {yy_left_string = yytext; return KEYWORD;}
"/*" BEGIN(in_multiline_comment);
"//"[^ \n]* {yy_left_string = yytext; return COMMENT;}
[a-zA-Z_][a-zA-Z0-9_]* {yy_left_string = yytext; return ID;}
(("0x")[+-]?[0-9A-F]+) | ([+-]?[0-9]+) {yy_left_integer = atoi(yytext); return INTEGER;}
([+-]?[0-9]*\.[0-9]+)(E[+-]?[0-9]+)? {yy_left_double = atof(yytext); return FLOAT_NUMBER;}
\" {BEGIN(in_string);}
<in_string>{
[\.?] {yy_left_string = yytext; return SPECIAL_CHARACTER;}
[^\"\]* {strncpy(yy_left_string, yytext + 1, strlen(yytext -1)); return SOME_STRING;}
\" {yy_left_string = yytext; BEGIN(INITIAL); return ENDING_DOUBLE_QUOTE;}
}
\(.?) {yy_left_string = yytext; return SPECIAL_CHARACTER;}
\'[^ \']?\' {yy_left_string = yytext; return SOME_CHARACTER;}
<in_multiline_comment>{
"*/" {yy_left_string = yytext; BEGIN(INITIAL); return MULTILINE_COMMENT;}
^[*\n]+
"*"
"\n" yylineno++;
}
[\n] {yylineno++;}
[\t\v] {}
. {yy_left_string = yytext;}
%%
int main(int argc, char** argv)
{
int token;
if(argc > 1){
if(!(yyin = fopen(argv[1], "r"))){
perror(argv[1]);
return 1;
}
}
FILE* highlighted_html_file = fopen("highlighted.html", "w");
if(highlighted_html_file == NULL){
printf("error opening file\n");
return 1;
}
while(token = yylex()){
if(token == KEYWORD){fprintf(highlighted_html_file,"<b><span style=\"color:Blue\">%s</span> </b>", yy_left_string);}
else if(token == ID){fprintf(highlighted_html_file,"<span style = \"color:Orange\"> %s </span>", yy_left_string);}
else if(token == INTEGER){fprintf(highlighted_html_file, "<span style = \"color:Purple\"> %d </span>", yy_left_integer);}
else if(token == FLOAT_NUMBER){fprintf(highlighted_html_file, "<i><span style = \"color:Purple\">%f</span></i>", yy_left_double);}
else if(token == SPECIAL_CHARACTER){fprintf(highlighted_html_file, "<span style = \"color:LightBlue\"> \"%s </span>", yy_left_string);}
else if(token == SOME_STRING){fprintf(highlighted_html_file, "<span style = \"color:Red\"> \"%s", yy_left_string);}
else if(token == ENDING_DOUBLE_QUOTE){fprintf(highlighted_html_file, "<span style = \"color:Red>\"</span>");}
else if(token == SOME_CHARACTER){fprintf(highlighted_html_file, "<span style = \"color:LightRed\"> \"%s </span>", yy_left_string);}
else if(token == COMMENT || token == MULTILINE_COMMENT){fprintf(highlighted_html_file, "<span style = \"color:Grey\"> %s</span>", yy_left_string);}
else {fprintf(highlighted_html_file, "%s", yy_left_string);}
}
}
枚举 token_type KEYWORD 的值为 0,如果您的标记为 0,则循环终止。 变化
enum token_type{
KEYWORD,
成为:
enum token_type{
KEYWORD = 1,
这个问题就会消失。
据我所知,您不应该仅使用变量赋值将 "yytext" 复制到您的变量。你应该使用 strdup 或类似的东西复制它。
此外,下面的代码很糟糕:
<in_string>{
[\.?] {yy_left_string = yytext; return SPECIAL_CHARACTER;}
[^\"\]* {strncpy(yy_left_string, yytext + 1, strlen(yytext -1)); return SOME_STRING;}
什么是手段?这意味着如果你处理 \a,那么你将执行 "yy_left_string = yytext"。 IE。现在 yy_left_string 是 "char*" 指向 flex 内部的一些内存。假设您处理普通字符,例如 z。现在你做 "strncpy(yy_left_string,...)"。因此,您将 yy_left_string(即指向某个 flex 内部内存的指针!!!)传递给 strncpy。因此,您将一些数据写入 flex 内部。这可以打破一切。而且您甚至不知道 yy_left_string 是否有足够的 space 来存储所有 yytext 字符。所以,你很容易陷入分段错误。
你了解 C 中的内存是如何工作的吗?你了解指针等吗?你了解 C 中的字符串处理吗?
另外,我不确定我提供的所有关于 yytext 的信息。 IE。我不确定 yytext 是否真的不应该存储在您的变量中。而且我不确定写入 yytext 指向的内存是不是个好主意。阅读 flex 文档以获取所有这些信息。
(另外,你的标签 "flex" 是错误的,因为它是关于其他 flex 的。)