加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

flex / bison解析器编译分段错误

发布时间:2020-12-15 01:45:38 所属栏目:百科 来源:网络整理
导读:我正在编写一个带有flex / bison的解析器(我可以用 Python编写解析器,但我总是喜欢经典.) 当我用这个编译代码时: gcc -lfl -ly chance.tab.c lex.yy.c -o chance 当我用文件运行程序时,我得到这样的东西: Segmentation fault (core dumped) 对于任何人的参
我正在编写一个带有flex / bison的解析器(我可以用 Python编写解析器,但我总是喜欢经典.)

当我用这个编译代码时:

gcc -lfl -ly chance.tab.c lex.yy.c -o chance

当我用文件运行程序时,我得到这样的东西:

Segmentation fault (core dumped)

对于任何人的参考,这里是文件:

chance.y

%{
    #include <stdio.h>
%}

%union {
    char* str;
}

%token ASSERT BREAK CATCH CLASS CONTINUE DEL EACH ELSE ELSEIF FINALLY FROM
%token FUNC IF LOAD PASS PRINT REPEAT RETURN RUN THROW TRY WHILE UNTIL
%token YIELD AND OR NOT KTRUE KFALSE NONE

%token MINUS EXCLAM PERCENT LAND LPAREN RPAREN STAR COMMA DOT SLASH COLON
%token SEMICOLON QUESTION AT LBRACKET BACKSLASH RBRACKET CIRCUMFLEX LBRACE
%token BAR RBRACE TILDE PLUS LTHAN EQUAL GTHAN INTDIV

%token ADDASS SUBASS MULASS DIVASS INTDASS MODASS ANDASS ORASS LTEQ EQUALS
%token GTEQ INCREMENT DECREMENT DBLSTAR

%token<str> NAME STRING INTEGER FLOAT
%token INDENT DEDENT NEWLINE

%type<str> exprs names args kwdspec dfltarg arg arglist exprlist name namelist
%type<str> funcargs parenexpr lstexpr eachspec optargs inheritance addop
%type<str> expr ifs elifs elif elses trys catchs catchx finally suite stmts
%type<str> stmt program

%start program

%%

exprs: expr                         { $$= $1; }
|   exprs COMMA expr                { sprintf($$,"%s %s",$1,$3); }
;

names: name                         { $$= $1; }
|   names COMMA name                { sprintf($$,$3); }
;

args: arg                           { $$= $1; }
|   args COMMA arg                  { sprintf($$,$3); }
;

kwdspec:                            { $$= "regular"; }
|   STAR                            { $$= "list"; }
|   DBLSTAR                         { $$= "keyword"; }
;

dfltarg:                            { $$= "null"; }
|   EQUAL expr                      { $$= $2; }
;

arg: kwdspec name dfltarg
        { sprintf($$,"(argument %s %s %s)",$2,$3); } ;

arglist: args                       { sprintf($$,"[%s]",$1); } ;
exprlist: exprs                     { sprintf($$,$1); } ;
name: NAME                          { sprintf($$,"(name %s)",$1); } ;
namelist: names                     { sprintf($$,$1); } ;
funcargs: LPAREN arglist RPAREN     { $$= $2 } ;
parenexpr: LPAREN exprlist RPAREN   { sprintf($$,"(tuple %s)",$2); } ;
lstexpr: LBRACKET exprlist RBRACKET { sprintf($$,"(list %s)",$2); } ;

eachspec: BAR namelist BAR          { sprintf($$,"(each-spec %s)",$2); } ;

optargs:                            { $$= ""; }
|   funcargs                        { $$= $1; }
;

inheritance:                        { $$= ""; }
|   parenexpr                       { $$= $1; }
;

addop:
    ADDASS                          { $$= "add"; }
|   SUBASS                          { $$= "sub"; }
|   MULASS                          { $$= "mul"; }
|   DIVASS                          { $$= "div"; }
|   INTDASS                         { $$= "int-div"; }
|   MODASS                          { $$= "mod"; }
|   ANDASS                          { $$= "and"; }
|   ORASS                           { $$= "or"; }
;

expr:       /* NotYetImplemented! */
    NUMBER                          { sprintf($$,"(number %s)",$1); }
|   TRUE                            { $$= "(true)"; }
|   FALSE                           { $$= "(false)"; }
|   NONE                            { $$= "(none)"; }
|   STRING                          { sprintf($$,"(string %s)",$1); }
|   lstexpr                         { $$= $1; }
;

ifs: IF expr suite                  { sprintf($$,"(if %s %s)",$3); } ;

elifs:                              { $$= ""; }
|   elifs elif                      { sprintf($$,$2); }
;

elif: ELSEIF expr suite             { sprintf($$,"(else-if %s %s)",$3); } ;

elses:                              { $$= ""; }
|   ELSE suite                      { sprintf($$,"(else %s)",$2); }
;

trys: TRY suite                     { sprintf($$,"(try %s)",$2); } ;

catchs:                             { $$= ""; }
| catchs catchx                     { sprintf($$,$2); }
;

catchx: CATCH expr suite            { sprintf($$,"(catch %s %s)",$3); } ;

finally: FINALLY suite              { sprintf($$,"(finally %s)",$2); } ;

suite: COLON stmts SEMICOLON        { sprintf($$,"(block [%s])",$2); } ;

stmts:                              { $$= ""; }
|   stmts NEWLINE stmt              { sprintf($$,$3); }
;

stmt:
    ASSERT expr                     { printf("(assert %s)",$2); }
|   BREAK                           { printf("(break)"); }
|   CATCH expr suite                { printf("(catch %s %s)",$3); }
|   CLASS name inheritance suite    { printf("(class %s %s %s)",$3,$4); }
|   CONTINUE                        { printf("(continue)"); }
|   DEL expr                        { printf("(del %s)",$2); }
|   expr DOT EACH eachspec suite    { printf("(each %s %s %s)",$4,$5); }
|   FROM name LOAD namelist         { printf("(from %s %s)",$4); }
|   FUNC name optargs suite         { printf("(func %s %s %s)",$4); }
|   ifs elifs elses                 { printf("(if-block %s %s %s)",$3); }
|   LOAD namelist                   { printf("(load %s)",$2); }
|   PASS                            { printf("(pass)"); }
|   PRINT expr                      { printf("(print %s)",$2); }
|   REPEAT expr suite               { printf("(repeat %s %s)",$3); }
|   RUN expr                        { printf("(run %s)",$2); }
|   THROW expr                      { printf("(throw %s)",$2); }
|   trys catchs elses finally       { printf("(try-block %s %s %s %s)",$4); }
|   WHILE expr suite                { printf("(while %s %s)",$3); }
|   UNTIL expr suite                { printf("(until %s %s)",$3); }
|   YIELD expr                      { printf("(yield %s)",$2); }
|   RETURN expr                     { printf("(return %s)",$2); }
|   expr addop expr                 { printf("(%s-assign %s %s)",$3); }
|   expr INCREMENT                  { printf("(increment %s)",$1); }
|   expr DECREMENT                  { printf("(decrement %s)",$1); }
|   expr                            { printf("(expr-stmt %s)",$1); }
;

program: stmts                      { printf("(program [%s])",$1); } ;

chance.l

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

    #include "parser.tab.h"
%}

%option yylineno
%option noyywrap

%%

"assert"    { return ASSERT; }
"break"     { return BREAK; }
"catch"     { return CATCH; }
"class"     { return CLASS; }
"continue"  { return CONTINUE; }
"del"       { return DEL; }
"each"      { return EACH; }
"else"      { return ELSE; }
"elseif"    { return ELSEIF; }
"finally"   { return FINALLY; }
"from"      { return FROM; }
"func"      { return FUNC; }
"if"        { return IF; }
"load"      { return LOAD; }
"pass"      { return PASS; }
"print"     { return PRINT; }
"repeat"    { return REPEAT; }
"return"    { return RETURN; }
"run"       { return RUN; }
"throw"     { return THROW; }
"try"       { return TRY; }
"while"     { return WHILE; }
"until"     { return UNTIL; }
"yield"     { return YIELD; }
"and"       { return AND; }
"or"        { return OR; }
"not"       { return NOT; }
"true"      { return KTRUE; }
"false"     { return KFALSE; }
"none"      { return NONE; }

-           { return MINUS; }
!           { return EXCLAM; }
%           { return PERCENT; }
&           { return LAND; }
(          { return LPAREN; }
)          { return RPAREN; }
*          { return STAR; },{ return COMMA; }
.          { return DOT; }
/          { return SLASH; }
:           { return COLON; }
;           { return SEMICOLON; }
?          { return QUESTION; }
 @          { return AT; }
[          { return LBRACKET; }
]          { return RBRACKET; }
^          { return CIRCUMFLEX; }
{          { return LBRACE; }
}          { return RBRACE; }
|          { return BAR; }
~           { return TILDE; }
+          { return PLUS; }
&;          { return LTHAN; }
=           { return EQUAL; }
&;          { return GTHAN; }
//        { return INTDIV; }
+=         { return ADDASS; }
-=          { return SUBASS; }
*=         { return MULASS; }
/=         { return DIVASS; }
//=       { return INTDASS; }
%=          { return MODASS; }
&=          { return ANDASS; }
|=         { return ORASS; }
&;=         { return LTEQ; }
==          { return EQUALS; }
&;=         { return GTEQ; }
++        { return INCREMENT; }
--          { return DECREMENT; }
**        { return DBLSTAR; }

[[:digit:]]+([eE][+-]?[[:digit:]]+)?                { yylval.str = strdup(yytext); return INTEGER; }
[[:digit:]]+.[[:digit:]]+([eE][+-]?[[:digit:]]+)?  { yylval.str = strdup(yytext); return FLOAT; }
[a-zA-Z_][a-zA-Z0-9_]*                              { yylval.str = strdup(yytext); return NAME; }

"([^"])*"    { yylval.str = strdup(yytext); return STRING; }
'([^'])*'    { yylval.str = strdup(yytext); return STRING; }
`([^`])*`       { yylval.str = strdup(yytext); return STRING; }

"<INDENT>"  { return INDENT; }
"<DEDENT>"  { return DEDENT; }
"<NEWLINE>" { return NEWLINE; }

#.*         { }

[ t]     {}
n          { (yylineno) += 0.5; }
.           { yyerror(); }

%%

int yyerror(void)
{
    printf("Invalid syntax on line %d: '%s'n",yylineno,yytext);
}

int main()
{
    yyparse();
    printf("n");
    return 0;
}

如果上述程序适用于任何人,请使用我的小编程语言中的一些示例代码:

test.ch

from timer load x

func x(f=0,**k):
    5.each|x|:
        continue;;

class OhHey:
    func __init__:
        print 5;;

while true:
    print x;

[1,2,3]
(1,3)

提前致谢. ~~机会

编辑:输入新的和改进的代码(不幸的是,仍然会产生段错误.)

解决方法

你的词法分析器从不设置yylval,所以当你的解析器读取一个令牌的值时,它会得到随机的垃圾.例如,在您的规则中:

expr: NUMBER { sprintf($$,$1); }

$1表示来自NUMBER的令牌值,因此将是随机垃圾.另外,$$是规则的输出,因此你传递给sprintf的值也将是随机垃圾(因为你没有先将它设置为某个东西).

编辑

一个“简单”的解决方案是大量使用strdup / asprintf为字符串分配内存.例如,在.l文件中,您将拥有以下内容:

[+-]?[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)? { yylval = strdup(yytext); return NUMBER; }

然后你的expr规则是:

expr: NUMBER { asprintf(&$$,$1); free($1); }

当然,问题在于弄清楚所有释放应该去哪里以避免泄漏记忆可能很困难.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读