English 中文(简体)
acc/ison
原标题:Segmentation fault with yacc/bison

I am trying to write a simple HTTP request parser for a school assignment but I have this segmentation fault that I can t get rid of. I think that my production rules are ok. I have executed bison with tracing enabled and it always produces a segfault at part where it parses my header:

Reducing stack by rule 9 (line 59):
   $1 = token ID ()
   $2 = token COLON ()
   $3 = token STRING ()
[4]    36661 segmentation fault (core dumped)  ./problem1 < input.txt

这里是我的请求书。

%option noyywrap
%{
    #include<stdio.h>
    #include "request.tab.h"
    char *strclone(char *str);
%}

num                                     [0-9]+(.[0-9]{1,2})?
letter                                  [a-zA-Z]
letternum                               [a-zA-Z0-9-]
id                                      {letter}{letternum}*
string                                  "[^"]*"
fieldvalue                              {string}|{num}

%%

(GET|HEAD|POST|PUT|DELETE|OPTIONS)      { yylval = strclone(yytext); return METHOD; }
HTTP/{num}                             { yylval = strclone(yytext); return VERSION; }
{id}                                    { yylval = strclone(yytext); return ID; }
"/"                                     { return SLASH; }
"
"                                    { return NEWLINE; }
{string}                                { yylval = strclone(yytext); return STRING; }
":"                                     { return COLON; }
[ 	
]+                                       ;
. {
    printf("Unexpected: %c
Exiting...
", *yytext);
    exit(0);
}

%%

char *strclone(char *str) {
    int len = strlen(str);
    char *clone = (char *)malloc(sizeof(char)*(len+1));
    strcpy(clone,str);
    return clone;
}

and my request.y file:

%{
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define YYSTYPE char*

extern int yylex();
extern int yyparse();
extern FILE* yyin;

void yyerror(const char* s);
%}

%token METHOD
%token SLASH
%token VERSION
%token STRING
%token ID
%token COLON
%token NEWLINE

%%

REQUEST: METHOD URI VERSION NEWLINE HEADERS {
       printf("%s %s", $1, $2);
    }
;

URI: SLASH DIR {
        $$ = (char *)malloc(sizeof(char)*(1+strlen($2)+1));
        sprintf($$, "//%s", $2);
    }
;

DIR: ID SLASH {
        $$ = (char *)malloc(sizeof(char)*(strlen($1)+2));
        sprintf($$, "%s//", $1);
    }
    |ID {
        $$ = $1;
    }
    | {
        $$ = "";
    }
;

HEADERS: HEADER {
        $$ = $1;
    }
    |HEADER NEWLINE HEADERS {
        $$ = (char *)malloc(sizeof(char)*(strlen($1)+1+strlen($3)+1));
        sprintf($$, "%s
%s", $1, $3);
    }
    |{
        $$ = "";
    }
;

HEADER: ID COLON STRING {
        $$ = (char *)malloc(sizeof(char)*(strlen($1)+1+strlen($2)+1));
        sprintf($$, "%s:%s", $1, $3);
    }
;

%%

void yyerror (char const *s) {
   fprintf(stderr, "Poruka nije tacna
");
}

int main() {
    yydebug = 1;
    yyin = stdin;

    do {
        yyparse();
    } while(!feof(yyin));

    return 0;
}

这里也是我的投入内容。

GET / HTTP/1.1
Host: "developer.mozzila.org"
Accept-language: "fr"
最佳回答

在<代码>request.y中,请列入指示

#define YYSTYPE char*

因此,在Bison所生成的子典中,yylval。 页: 1 但这一行文没有插入request.l。 因此,在灵活生成的扫描代码中,yylval 其缺省类型,int

You could fix this by adding the definition of YYSTYPE to your request.l file but then you have the same setting repeated in two places, which is a recipe for disaster. Instead, use Bison`s declaration syntax:

%define api.value.type { char* }

(说明:该词句,而不是C前处理器的定义,因此与你的其他Bison条码<>%指令有关。)

The advantage of this solution is that Bison also adds the declaration to the header file it produces. Since that file is #included in request.l, no modifications need to be made to your scanner.

C, unfortunately, allows a pointer to be converted to an integer type even if the integer type is too narrow to hold the entire address, which is the case with a typical 64-bit platform with 8-byte pointers and 4-byte int. So in your scanner, setting the value of what the compiler thinks is a four-byte int to an eight-byte pointer means that the value will be truncated. So when the parser attempts to use it as an address, you ll get a segfault. If you re lucky.

Most C compilers will warn you about this truncation -- but only if you tell the compiler that you want to see warnings (-Wall for clang and gcc). Compiling with -Wall is always important, even when compiling the output of a code generator.

您还需要确定@JakobStark

问题回答
HEADER: ID COLON STRING {
    $$ = (char *)malloc(sizeof(char)*(strlen($1)+1+strlen($2)+1));
    sprintf($$, "%s:%s", $1, $3);
};

Shouldn t you use strlen($3) in the expression, where you calculate the length of the combined string? strlen($2) as you use will only return the length of the colon string which should be 1. If you then sprintf to the buffer which is too short, you access the buffer behind it s length.

I got this error too in the past few days. I was trying to imatate the /bison/examples/c/glr. I used a union as value type. I got this error because the return type of token defined in lexer.l is not 1 of the union.struct types, and flex will not warn the mistake.





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签