簡體   English   中英

簡單Bison腳本上的分段錯誤

[英]Segmentation fault on simple Bison script

好的,我正在使用Lex / Bison(Yacc)做一些實驗,並且鑒於我的C技能還很生銹(我曾經用所有這些工具創建過編譯器和東西,現在我迷失了前幾行...:-S),我需要您的幫助。

這是我的解析器的外觀:

%{
#include <stdio.h>
#include <string.h>

void yyerror(const char *str)
{
    fprintf(stderr,"error: %s\n",str);
}

int yywrap()
{
    return 1;
} 

main()
{
    yyparse();
} 

%}

%union 
{
    char* str;
}

%token <str> WHAT IS FIND GET SHOW WITH POSS OF NUMBER WORD

%type <str> statement
%start statements
%%

statement
    : GET { printf("get\n"); }
    | SHOW  { printf("%s\n",$1); }
    | OF { printf("of\n"); }
    ;

statements
    : statement
    | statements statement
    ;

問題 :

因此,基本上,只要解析器遇到“ get”,它就會打印“ get”。 等等。

但是,當嘗試打印“顯示”(使用$1指定符)時,它會發出segmentation fault錯誤。

我究竟做錯了什么?

Lex返回一個代表令牌的數字,您需要訪問yytext以獲取解析內容的文本。

就像是

statement               : GET { printf("get\n"); }
                        | SHOW  { printf("%s\n",yytext); }
                        | OF { printf("of\n"); }
                        ;

為了傳播終端文本,我繼續將非終端與終端相關聯,然后傳回char *並開始構建解析樹。 注意,我省略了decl類型和create_sww_ASTNode(char *,char *,char *)的實現; 但是,重要的是,並非所有非終結符都將返回相同的類型,因為number是整數,單詞return char * sww return astNode(或您想到的任何通用抽象語法樹結構)。 通常在非終端代表終端之外,所有都是AST東西。

sww                     : show word word
                        {
                           $$ = create_sww_ASTNode($1,$2,$3);
                        }
                        ;

word                    : WORD
                        { 
                          $$ = malloc(strlen(yytext) + 1);
                          strcpy($$,yytext);
                        }
                        ;

show                    : SHOW
                        { 
                          $$ = malloc(strlen(yytext) + 1);
                          strcpy($$,yytext);
                        }
                        ;

number                  : NUMBER
                        { 
                           $$ = atoi(yytext);
                        }
                        ;

您沒有顯示您的詞法分析器代碼,但是問題可能是您從未將yylval設置為任何值,因此,當您在解析器中訪問$1時,它包含垃圾並導致崩潰。 您的詞法分析器操作需要將yylval.str設置為某種值,這樣它才有效:

"show"   { yylval.str = "SHOW"; return SHOW }
[a-z]+   { yylval.str = strdup(yytext); return WORD; }

好的,這就是答案(有人可以告訴我,我已經在這里發布了一個問題后,我總是想出解決方案是什么嗎?)

問題在於解析器本身,而在於Lexer。

問題是:當您將其告訴{ printf("%s\\n",$1); } { printf("%s\\n",$1); } ,實際上我們告訴它打印yylval (默認情況下是int ,而不是字符串)。

因此,訣竅是將適當的標記轉換為字符串。

這是我的(更新的)Lexer文件:

%{
#include <stdio.h>
#include "parser.tab.h"

void toStr();
%}

DIGIT               [0-9]
LETTER              [a-zA-Z]
LETTER_OR_SPACE     [a-zA-Z ]

%%

find    { toStr(); return FIND; }
get     { toStr(); return GET; }
show    { toStr(); return SHOW; }

{DIGIT}+(\.{DIGIT}+)?   { toStr(); return NUMBER; }
{LETTER}+               { toStr(); return WORD; }
\n                      /* ignore end of line */;
[ \t]+                  /* ignore whitespace */;
%%

void toStr()
{
    yylval.str=strdup(yytext);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM