在打印$ 1时,它会在野牛中打印$ 1,$ 2,$ 3等的值

时间:2014-08-20 04:10:45

标签: bison

我编写了一个使用flex和bison来解析文件的程序。 yylval通过flex正确返回,当我尝试在我的野牛代码中打印$ 1值时,它还会打印$ 2,$ 3 .. 我怎么能摆脱这个。我附上了我的弹性和野牛代码。

setuplog.l

%{  
    #include <stdio.h>
    #include "setuplog.tab.h"
    #include <string.h>
    int yyline=1;

%}

time            ([0-9]+\:[0-9]+\:[0-9]+\.[0-9]+)
date            ([0-9]+\/[0-9]+\/[0-9]+)
identifier      [_A-Za-z0-9=\.:\\()&#'-]+    
%%


"(["{identifier}"])"    {
                            return(DATA);
                        }

{identifier}"!"         {

                            yylval=yytext;
                            printf("FRM LEXER ID = %s %s\n",yytext,yylval);
                            return(IDENTIFIER);
                        }

"["         {
                printf("OPEN\n");
                return(OPEN_TOK);
            }

"]"         {
                printf("CLOSE\n");
                return(CLOSE_TOK);
            }

">>>"       {
                return (START_TOK); 
            }

"<<<"       {
                printf("END TOKEN\n");
                return (END_TOK);
            }

"!!!"      {
                return(ERROR_TOK);
           }

"!"        {
                return(WARN_TOK);

            }

"Boot"      {
                return(BOOT_TOK);
            }

\n          {
                yyline++;
            }


{time}     {

                    yylval=yytext;
                    printf("FRM LEXER TIME= %s %s\n",yytext,yylval);
                    return(TIME);
            }

{date}      {

                    yylval=yytext;
                    printf("FRM LEXER DATE= %s %s\n",yytext,yylval);
                    return(DATE);
            }


{identifier}    {

                    yylval=yytext;
                    printf("FRM LEXER ID = %s %s\n",yytext,yylval);
                    return(IDENTIFIER);
                }


%%

int yywrap(void)
{
  return 1;
}

setuplog.y

%{

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

extern int yyline;
int set_count=1;
FILE *fp;
extern char* yytext;
%}


%token  OPEN_TOK
%token  CLOSE_TOK 
%token  START_TOK   
%token  END_TOK   
%token  ERROR_TOK
%token  WARN_TOK  
%token  BOOT_TOK
%token  TIME
%token  DATE
%token DATA
%token  IDENTIFIER 

%start session
%%

session : boot_data section_start
        {
            printf("SESSION\n");
            fprintf(fp,"\n\nNO.OF LINES PARSED = %d\n",yyline);
        }
        ;

boot_data : head_desc statement head_desc head_desc
        {
            printf("BOOT_DATA\n");
        }
        ;

head_desc :OPEN_TOK statement CLOSE_TOK
        {
            printf("NON BOOT DATA--%s\n",$2);
            $$=$2;
        }
       |    OPEN_TOK BOOT_TOK statement CLOSE_TOK
        {
            printf("HEAD_DESCRIPTION\n$2=%s\nyytext=%s\n\n",$2,yytext);
            $$=$3;
            fprintf(fp,"\n[Boot %s\n",$3);

        }
        ;

statement : word
        {
            printf("WORD\n");
            $$=$1;
        } 
        |statement word 
        {
            printf("STATEMENTS\n");
            $$=$1;
            printf("STATEMENT VALUE== %s\n\n",$$);
        }
        ;

word :  TIME
        {
            printf("TIME\n");
            $$=$1;
        }
        |DATE
        {
            printf("DATE\n");
            $$=$1;
        }
        |DATA
        {
        }
        | IDENTIFIER
        {
            printf("IDENTIFIER\n");
            $$=$1;
        } 
        ;
 section_start : section_details 
        {
            printf("SINGLE SECTIONS\n");        
        } 
        |section_start section_details
        {
            printf("MULTIPLE SECTIONS\n");   
        } 
        |section_start head_desc section_details
        ; 

section_details :
            {
                fprintf(fp,"\n%d:\n",set_count); 
            }
            section_head section_body section_end
            {
                printf("SECTION DETAILS\n");
                set_count++;

            }
            ;

section_head : START_TOK head_desc START_TOK statement DATE TIME
             {
                printf("SECTION HEAD...\n\n%s===\n\n%s\n",$2,$4);
                fprintf(fp,"%s\n",$2);

             }
             ;

section_body :log_entry
            {

            }
            |section_body log_entry
            {

            }
            ;

log_entry : entry_prefix time_stamp body_statements
            {

            } 
            ;

time_stamp:DATE TIME
            {
                printf("DATE AND TIME\n");
            }
            |
            {

            }

            ;
body_statements : statement
            {

            }
            |head_desc
            {

            }
            ;

entry_prefix : ERROR_TOK
            {
                fprintf(fp,"%s","Error Message\n");
            }
            |WARN_TOK
            {
                fprintf(fp,"%s","Warning Message\n");
            } 
            |
            {
                printf("INFORMATION MESSAGE\n");
            }
            ;

section_end :END_TOK statement
            {

            }
            END_TOK head_desc
            {
                     printf("SECTION END...\n\n%s===\n\n%s\n",$2,$5);
                     fprintf(fp,"%s\n",$2);
            }
            ;


%%

yyerror(char *str)
{
    printf("Parse error: %s at line %d ,",str,yyline);
    yywhere(); 
}

yywhere()
{   
    int colon=0;
    int i;
    if(yytext) 
    { 
        for(i=0;i<50;i++) if(!yytext[i] || yytext[i] == '\n') break;
        if(i)
        {  
            if(!colon)  
            { 
                printf(" near: \"%s\"\n",  yytext);
                colon = 1; 
            }
        }  
        printf("\n");
    }  
}   

int main(void) 
{
    int i =remove("output.txt");
    fp=fopen("output.txt","a+");

    yyparse();
    fclose(fp);
}

1 个答案:

答案 0 :(得分:2)

这可能是关于野牛/ lex语法的头号常见问题解答。

简短回答:您需要复制yytext,因为当lex读取下一个标记时它会被修改。

bison FAQ中的答案更长。