Compilation yacc和lex中的yytext累积问题

Compilation yacc和lex中的yytext累积问题,compilation,abstract-syntax-tree,yacc,lex,preorder,Compilation,Abstract Syntax Tree,Yacc,Lex,Preorder,我试图打印AST并在树中打印标识符的实际名称。 我用的是lex和yacc 出于某种原因,yacc会将所有标记提前读取到一行中,直到“;”这会阻止我使用yytext访问标识符的文本值 这是lex文件: %{ %} %% "&&" {return OP_AND;} \"|"\"|" {return OP_OR;} != {return OP_NE;} == {return OP_EQ;} > {return OP_GT;

我试图打印AST并在树中打印标识符的实际名称。 我用的是lex和yacc

出于某种原因,yacc会将所有标记提前读取到一行中,直到“;”这会阻止我使用yytext访问标识符的文本值

这是lex文件:

%{

%}



%%
"&&"      {return OP_AND;}
\"|"\"|"    {return OP_OR;} 
!=      {return OP_NE;}
==      {return OP_EQ;}
>       {return OP_GT;}
>=      {return OP_GE;}
\<      {return OP_LT;}
\<=     {return OP_LE;}
!       {return OP_NOT;}
=       {return ASSIGN;}
\+      {return PLUS;}
\-      {return MINUS;}
\*      {return MULT;}
\/      {return DIV;}
\&      {return ADRS;}
\^      {return PTR_VAL;}
\;  {return SEMI;}
,   {return COMMA;}
\{  {return CURLY_O;}
\}  {return CURLY_C;}
\(  {return PAREN_O;}
\)  {return PAREN_C;}
\|      {return BAR;}
\[  {return SQR_O;}
\]  {return SQR_C;}
else      {return ELSE;}
if        {return IF;}
do      {return DO;}
for        {return FOR;}
bool   {return BOOL;}
void   {return VOID;}
int { return INT;}
charp   {return CHARP;}
intp   {return INTP;}
string   {return STRING;}
while       {return WHILE;}
true      {return TRUE_;}
false     {return FALSE_;}
return    {return RETURN;}
null        {return NULL_;}



0|[1-9][0-9]*           {return CONST_INT;}

[a-zA-Z][a-zA-Z0-9]*           { return IDENT;}

\'.\'       {return CONST_CHAR; }
\".*\"  {return CONST_STRING; }

\[\$([^\$]*\$+[^\]])*[^\$]*\$+\]    { /*comment*/}

[ \n\t]   { /* skip whitespace */}

.     {return ILLEAGAL;}


%%
void main(int x){
    int y,w,r; int z;
}
FUNC
    void
        main
        int x
            x
        BODY
            DECL
                int z;
                    ;
                DECL
                    int y,w,r;
                        ,
                            ;
                            ,
                                ,
                                ,
FUNC
    void
        main
        int
            x
        BODY
            DECL
                int
                    z
                DECL
                    int 
                        ,
                            y
                            ,
                                w
                                r
这是预订单中的输出AST:

%{

%}



%%
"&&"      {return OP_AND;}
\"|"\"|"    {return OP_OR;} 
!=      {return OP_NE;}
==      {return OP_EQ;}
>       {return OP_GT;}
>=      {return OP_GE;}
\<      {return OP_LT;}
\<=     {return OP_LE;}
!       {return OP_NOT;}
=       {return ASSIGN;}
\+      {return PLUS;}
\-      {return MINUS;}
\*      {return MULT;}
\/      {return DIV;}
\&      {return ADRS;}
\^      {return PTR_VAL;}
\;  {return SEMI;}
,   {return COMMA;}
\{  {return CURLY_O;}
\}  {return CURLY_C;}
\(  {return PAREN_O;}
\)  {return PAREN_C;}
\|      {return BAR;}
\[  {return SQR_O;}
\]  {return SQR_C;}
else      {return ELSE;}
if        {return IF;}
do      {return DO;}
for        {return FOR;}
bool   {return BOOL;}
void   {return VOID;}
int { return INT;}
charp   {return CHARP;}
intp   {return INTP;}
string   {return STRING;}
while       {return WHILE;}
true      {return TRUE_;}
false     {return FALSE_;}
return    {return RETURN;}
null        {return NULL_;}



0|[1-9][0-9]*           {return CONST_INT;}

[a-zA-Z][a-zA-Z0-9]*           { return IDENT;}

\'.\'       {return CONST_CHAR; }
\".*\"  {return CONST_STRING; }

\[\$([^\$]*\$+[^\]])*[^\$]*\$+\]    { /*comment*/}

[ \n\t]   { /* skip whitespace */}

.     {return ILLEAGAL;}


%%
void main(int x){
    int y,w,r; int z;
}
FUNC
    void
        main
        int x
            x
        BODY
            DECL
                int z;
                    ;
                DECL
                    int y,w,r;
                        ,
                            ;
                            ,
                                ,
                                ,
FUNC
    void
        main
        int
            x
        BODY
            DECL
                int
                    z
                DECL
                    int 
                        ,
                            y
                            ,
                                w
                                r
我期望的输出:

%{

%}



%%
"&&"      {return OP_AND;}
\"|"\"|"    {return OP_OR;} 
!=      {return OP_NE;}
==      {return OP_EQ;}
>       {return OP_GT;}
>=      {return OP_GE;}
\<      {return OP_LT;}
\<=     {return OP_LE;}
!       {return OP_NOT;}
=       {return ASSIGN;}
\+      {return PLUS;}
\-      {return MINUS;}
\*      {return MULT;}
\/      {return DIV;}
\&      {return ADRS;}
\^      {return PTR_VAL;}
\;  {return SEMI;}
,   {return COMMA;}
\{  {return CURLY_O;}
\}  {return CURLY_C;}
\(  {return PAREN_O;}
\)  {return PAREN_C;}
\|      {return BAR;}
\[  {return SQR_O;}
\]  {return SQR_C;}
else      {return ELSE;}
if        {return IF;}
do      {return DO;}
for        {return FOR;}
bool   {return BOOL;}
void   {return VOID;}
int { return INT;}
charp   {return CHARP;}
intp   {return INTP;}
string   {return STRING;}
while       {return WHILE;}
true      {return TRUE_;}
false     {return FALSE_;}
return    {return RETURN;}
null        {return NULL_;}



0|[1-9][0-9]*           {return CONST_INT;}

[a-zA-Z][a-zA-Z0-9]*           { return IDENT;}

\'.\'       {return CONST_CHAR; }
\".*\"  {return CONST_STRING; }

\[\$([^\$]*\$+[^\]])*[^\$]*\$+\]    { /*comment*/}

[ \n\t]   { /* skip whitespace */}

.     {return ILLEAGAL;}


%%
void main(int x){
    int y,w,r; int z;
}
FUNC
    void
        main
        int x
            x
        BODY
            DECL
                int z;
                    ;
                DECL
                    int y,w,r;
                        ,
                            ;
                            ,
                                ,
                                ,
FUNC
    void
        main
        int
            x
        BODY
            DECL
                int
                    z
                DECL
                    int 
                        ,
                            y
                            ,
                                w
                                r
当我进入规则:在我的yacc文件中键入yytext时,可以看到它包含整个句子(“int y,w,r;”而不是“int”),当我进入规则:id时,它只包含一个令牌,恰好是一个令牌,然后是预期的令牌。
-请注意,在函数名和函数参数中,文本可以正常工作

-我尝试从lex文件打印yytext,标记似乎包含正确的值。

yytext
指向扫描的最后一个lexeme。以前保存到扫描仪intrrnal缓冲区中的任何其他指针(例如以前的值
yytext
)无效,不能假定X指向任何有用的东西

在解析器操作中,您几乎不知道最后扫描的标记是什么。Yacc/bison生成LALR(1)解析器,其中
1
表示“一个前瞻令牌”。这意味着解析器(可以)始终检查下一个标记,如果它这样做,则标记
yytext
将指向。有些实现总是提前阅读;其他人,如bison,如果前瞻不会改变解析器的行为,则有时不进行前瞻性阅读。因此,在解析器操作期间,哪个标记
yytext
指向哪个标记是未指定的,并且可能在将来的版本中或使用不同的实现进行更改

底线:千万不要在解析器操作中使用
yytext
。不要将
yytext
的指针值从扫描仪传递到解析器。如果您需要解析器中令牌的字符串值,请复制该字符串并通过
yylval
将副本的地址传递给解析器。如果您使用了
strdup
或类似工具,请不要忘记在不再需要副本时
释放副本