代码之家  ›  专栏  ›  技术社区  ›  foobarfuzzbizz

YYParse正在打印前导选项卡

  •  0
  • foobarfuzzbizz  · 技术社区  · 15 年前

    在我的bison/flex程序中,在调用yyparse()之后,会打印一个前导标签,但我不知道为什么。你知道怎么了吗?

    这将调用bison代码,并在yyparse()返回后立即打印一个选项卡。

    void parseArguments(int argc, char** argv)
    130 {
    131     int i;
    132 
    133     int sum = 0;
    134     // calculate the length of buffer we need
    135     for(i = 1; i < argc; i++)
    136     {
    137         sum += strlen(argv[i]) + 1;
    138     }
    139 
    140     if(sum <= 0)
    141         return;
    142 
    143     // make us a buffer and zero it out
    144     char tempBuffer[sum];
    145     memset(tempBuffer, 0, sum);
    146 
    147     // pointer to walk through our buffer
    148     int pos = 0;
    149 
    150     // copy arguments into the buffer
    151     for(i = 1; i < argc; i++)
    152     {
    153         memcpy(tempBuffer+pos, argv[i], strlen(argv[i]));
    154         pos += strlen(argv[i]);
    155         sprintf(tempBuffer+pos++, " ");
    156     }
    157 
    158     // give our arguments to lex for parsing
    159     configBuffer(tempBuffer);
    160 
    
    
    // use bison parsing
    163     int returnVal = yyparse(); // after this returns a tab character has been printed
    
    
    164     if(returnVal != 0)                                                                                            
       165     {   
       166         printf("yyparse failed!\n");                                                                              
       167     }                                                                                                             
       168     
    

    我所有的bison规则都只是正则表达式和返回语句。我能看到的唯一对野牛感兴趣的影响就是:

    64 %%
     65 void configBuffer(char* arguments)
     66 {
     67 #ifdef DEBUG
     68     printf("Given the buffer: %s\n", arguments);
     69 #endif
     70     yy_delete_buffer(YY_CURRENT_BUFFER);
     71 
     72     yy_scan_string(arguments);
     73 }
    

    我试过几个人的建议,但还是不走运。这是我的完整flex文件:

    %{
    #include <string.h>
    #include "CommandParser.tab.h"
    %}
    
    %%
    
    \t {
        printf("TAB!\n");
    }
    
    " " {
        printf("SPACE!\n");
    }
    
    \n {
        return;
    }
    
    -p {
        return PRINTMODE; 
    }
    
    -x {
        return XORMODE;
    }
    
    -n {
        return NOTMODE;
    }
    
    -a {
        return ANDMODE;
    }
    
    -o {
        return ORMODE;
    }
    
    -r {
        return RANGEFLAG;
    }
    
    -l {
        return LENGTHFLAG;
    }
    
    0[xX][0-9a-fA-F]+ {
        int retVal = sscanf(yytext, "%x",&(yylval.int_val));
        if(retVal != 1)
            return;
        return NUMBER;
    }
    
    [0-9]+ {
        yylval.int_val = atoi(yytext);
        return NUMBER;
    }
    
    ['"].*+['"] {
        yylval.string_val = strdup(yytext);
        return ARGUMENT;
    }
    
    [^ \t\n]+ {
        yylval.string_val = strdup(yytext);
        return ARGUMENT;
    }
    
    
    %%
    void configBuffer(char* arguments)
    {
    #define DEBUG
    #ifdef DEBUG
        printf("Given the buffer: %s:\n", arguments);
    #endif
        yy_delete_buffer(YY_CURRENT_BUFFER);
        yy_scan_string(arguments);
    

    }

    1 回复  |  直到 11 年前
        1
  •  5
  •   Simeon Pilgrim    15 年前

    您的lexer中是否没有处理该选项卡,因此将应用默认的规则匹配和回显?

    多放一根火柴

    \t { printf("TAB"); }
    

    在结束代码部分之前输入代码。

    如果显示的是制表符而不是\t,则将printf转换为空语句

    \t { /*printf("TAB")*/; }
    

    在lex发布编辑之后:

    好的,在测试了你的lex之后,看起来你的匹配是正确的。

    我用这个代码来测试它

    #include <stdio.h>
    #include "CommandParser.tab.h"
    
    YYSTYPE yylval;
    
    int main(int argc, char* argv[])
    {
        while(1)
        {
            printf("lex:%d\r\n",yylex());
        }
        return 0;
    }
    
    extern "C" int yywrap();
    
    int yywrap ()
    {
        return 1;
    }
    

    所以通过输入(通过stdin)

    -a<\ >-x<\t>-p<space>-c<\r>
    

    我得到

    lex:103
    SPACE!
    lex:101
    TAB!
    lex:100
    SPACE!
    lex:108
    lex:3
    

    对于这个头文件

    #define PRINTMODE   100
    #define XORMODE     101
    #define NOTMODE     102
    #define ANDMODE     103
    #define ORMODE      104
    #define LENGTHFLAG  105
    #define RANGEFLAG   106
    #define NUMBER      107
    #define ARGUMENT    108
    #define DEFUALT     0
    
    typedef union {
        int int_val;
        char* string_val;
    } YYSTYPE;
    
    #ifdef __cplusplus
    extern "C" int yylex();
    
    extern "C" YYSTYPE yylval;
    #else // __cplusplus
    extern YYSTYPE yylval;
    #endif // __cplusplus
    

    所以我接下来要尝试的是替换 yyparse 用这个代码,看看你得到了什么。

    while(1)
    {
        printf("lex:%d\r\n",yylex());
    }
    

    如果你仍然打印标签,它不知何故是你的lexer,否则它不知何故是你的解析器/主程序。

    为了找到答案,我会用一个 const string 看看在这种情况下会发生什么。基本上,二进制搜索您的代码以找到问题点。