2010-07-27 79 views
2

我有一个非常简单的yacc/lex程序的问题。我可能忘记了一些基本步骤(从使用这些工具已经很长时间了)。yacc/lex的基本问题

在我的lex程序我提供一些基本的价值观,如:

word [a-zA-Z][a-zA-Z]* 
%% 
":" return(PV); 
{word} { 
      yylval = yytext; 
      printf("yylval = %s\n",yylval); 
      return(WORD); 
     } 
"\n" return(ENDLINE); 

在我的yacc程序我的语法开始是(其中TranslationUnit是我的%开始):

TranslationUnit: 
       /* Nothing */ 
       | InfoBlock Data 
       ; 

InfoBlock: 
      /* Nothing */ 
     | InfoBlock InfoExpression {} 
     ; 

InfoExpression: 
      WORD PV WORD ENDLINE { printf("$1 = %s\n",$1); 
printf("$2 = %s\n",$2); 
printf("$3 = %s\n",$3); 
printf("$4 = %s\n",$4); 
            } 
      | ... /* other things */ 
      ; 

Data: 
    ... /* other things */ 

当我与输入运行我的程序:

keyword : value 

我以为我会得到至少:

$1 = keyword 
$2 = keyword // yylval not changed for token PV 
$3 = value 
$4 = value // yylval not changed for token ENDLINE 

其实我得到:

$1 = keyword : value 
$2 = keyword : value 
$3 = value 
$4 = value 

我不明白这样的结果。我前段时间学过语法,即使我现在不记得任何事情,我也没有看到任何重要的错误...

在此先感谢您的帮助。

+0

Lex代码中的'{mot}'是否为'{word}'?哦,是的 - 你会说法语,而且你大部分都是为我们翻译的。 – 2010-07-27 14:14:13

+0

@Jonathan Leffler:对错误感到抱歉。我现在改变它。 – ThR37 2010-07-27 14:33:10

回答

3

问题是,除非您保存令牌,否则Lex/Yacc会继续覆盖空间,或指向不同的空间等。因此,您需要在修改之前隐藏对您至关重要的信息。用Lex代码打印时应该已经告诉您yylval值在词法分析器(词法分析器)被调用的时候是准确的。

另请参见SO 2696470其中遇到并诊断了相同的基本问题。

+0

非常感谢您的回答。 事实上,我在Lex代码中获得了良好的印刷效果。 为了解决我的问题,我试图通过添加缓冲区来更改代码: InfoExpression: \t WORD {memset(buffer,'\ 0',BUFFER_LENGTH);的sprintf(缓冲液, “%s” 时,$ 1); } PV WORD {sprintf(buffer,“%s ='%s'”,buffer,$ 1); } ENDLINE {printf(“%s \ n”,buffer);} \t; 但是这个修改我仍然得到: 关键字=“关键字:值” – ThR37 2010-07-27 15:47:27

+0

(评论:续) 所以我已经使用了以下解决方案(也许更清洁,但我不知道...): InfoExpression: InfoLValue PV InfoRValue ENDLINE {printf(“%s \ n”,buffer);} ; InfoLValue: WORD {memset(buffer,'\ 0',BUFFER_LENGTH); sprintf(缓冲区,“%s”,$ 1);} ; InfoRValue: WORD {sprintf的(缓冲器, “%S = '%s' 的”,缓冲器,$ 1);} ; – ThR37 2010-07-27 15:47:50