c++ - yyparse 正在打印前导标签

标签 c++ bison flex-lexer

在我的 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 规则都是与 return 语句配对的正则表达式。我能看到影响这一点的唯一对 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);

最佳答案

是否在您的词法分析器中未处理制表符,因此正在应用默认规则匹配和回显?

放一个额外的匹配

\t { printf("TAB"); }

进入结束代码部分之前的代码。

如果显示 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;
}

所以输入(通过标准输入)

-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());
}

如果你仍然打印出标签,那么它就是你的词法分析器,否则它就是你的解析器/主程序。

为了找出答案,我会用 const string 替换您创建的魔术字符串,然后看看在这种情况下会发生什么。基本上二进制搜索您的代码以找到问题点。

关于c++ - yyparse 正在打印前导标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1071804/

相关文章:

c - GCC 和 Flex/Bison 没有效果警告的声明

c++ - 我是否应该关心 4 级警告?

c++ - 在 Visual C++ Windows 应用程序中显示图像

c - 词法分析器正确输出但指针 "filename"包含错误名称

c++ - Flex++ 的常见问题

javascript - 使用 Flex 解析器解析 Javascript 代码

c++ - 我可以在不复制缓冲区的情况下从缓冲区初始化 iostream 吗?

c++ - 如何打印 QLabel?

c - YACC 文件是否有文件包含机制?

gcc - yylval 未定义,带有 flex 和 bison