我在C中有一个程序将表达式转换为RPN(反向波兰表示法)。 我需要做的就是用Flex替换用C编写的lexer代码。我已经做了一些工作,但我遇到了模式问题 - 单词或变量id是具体的。是的,这是课堂练习。
这就是我所拥有的:
%{
#include "global.h"
int lineno = 1;
int tokenval = NONE;
%}
%option noyywrap
WS " "
NEW_LINE "\n"
DIGIT [0-9]
LETTER [a-zA-Z]
NUMBER {DIGIT}+
ID {LETTER}({LETTER}|{DIGIT})*
%%
{WS}+ {}
{NEW_LINE} { ++lineno; }
{NUMBER} { sscanf (yytext, "%d", &tokenval); return(NUM); }
{ID} { sscanf (yytext, "%s", &tokenval); return(ID); }
. { return *yytext;}
<<EOF>> { return (DONE); }
%%
并在global.h
#define BSIZE 128
#define NONE -1
#define EOS '\0'
#define NUM 256
#define DIV 257
#define MOD 258
#define ID 259
#define DONE 260
当我使用数字,括号和运算符时,所有工作都有效,但当我输入例如a+b
时,它会给我Segmentation fault
(并且输出应为ab+
)。
请不要问我解析器代码(如果真的需要我可以共享) - 要求只使用Flex实现词法分析器。
答案 0 :(得分:2)
问题是程序正在使用字符串格式(sscanf
)对%s
进行整数地址(&tokenval
)。您应该将其更改为char
数组,例如
%{
#include "global.h"
int lineno = 1;
int tokenval = NONE;
char tokenbuf[132];
%}
和
{ID} { sscanf (yytext, "%s", tokenbuf); return(ID); }
(虽然strcpy
是比sscanf
更好的选择,但这只是一个起点。)
答案 1 :(得分:1)
当flex扫描令牌匹配模式ID
时,关联的操作会尝试将令牌复制到位置&tokenval
的字符数组中。但是tokenval
的类型为int
,所以
int
的大小,则您无法将其所有字节(包括字符串终止符)放在int
占用的空间中。一个可能的结果是你试图写出它的结尾,这可能会导致段错误。