2016-02-27 54 views
1

我正在做一个简单的编译器,并且我使用flex和散列表(unordered_set)来检查输入字是标识符还是关键字。Flex令牌不能使用char * hashtable

%{ 
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#include <unordered_set> 
using std::unordered_set; 
void yyerror(char*); 
int yyparse(void); 

typedef unordered_set<const char*> cstrset; 
const cstrset keywords = {"and", "bool", "class"}; 
%} 
%% 
[ \t\n\r\f]    ; 
[a-z][a-zA-Z0-9_]*  { if (keywords.count(yytext) > 0) 
           printf("%s", yytext); 
          else 
           printf("object-identifier"); }; 

%% 

void yyerror(char* str) {printf("ERROR: Could not parse!\n");} 
int yywrap() {} 

int main(int argc, char** argv) 
{ 
    if (argc != 2) {printf("no input file");} 
    FILE* file = fopen(argv[1], "r"); 
    if (file == NULL) {printf("couldn't open file");} 
    yyin = file; 
    yylex(); 
    fclose(file); 
    return 0; 
} 

我试图与只有写单词“类”的输入文件,输出是object_identifier,不class

我尝试了一个简单的程序,没有使用flex和unordered_set工作正常。

int main() 
{ 
    cstrset keywords = {"and", "class"}; 
    const char* str = "class"; 
    if (keywords.count(str) > 0) 
     printf("works"); 
    return 0; 
} 

可能是什么问题?

+1

标签为C++ 11:考虑'使用cstrset = unordered_set '而不是'typedef' – kfsone

回答

1

使用unordered_set<string>而不是您的unordered_set<const char*>。您试图找到指向char数组的指针,该数组显然不能存在于您定义的变量中。

+0

是的,这可能会工作,但使用const char *将帮助我稍后,所以我只会切换到字符串是不可能的。我不认为这是指针问题。我尝试了一个单独的测试程序,而不使用flex,并且工作正常。我将编辑该问题以显示此内容。 – devil0150

+0

为什么你更喜欢使用const char *?您可以随时在字符串对象上使用.c_str()来提取此类型的值... –

+1

您的示例程序可能因为编译器优化而起作用 - 编译器发现有两个具有相同值的常量字符数组,因此它在每个用法中使用相同的指针... –