来自不同流的解析器

时间:2014-07-17 15:25:01

标签: c bison lex

我们需要根据这个语法解析一个值:

%{
    ...
    #define YYSTYPE Pformatted
    extern FILE *formattedin;
    extern Value lexval;
%}
%token FORMATTED_LEX_ID CHARCONST INTCONST REALCONST STRCONST BOOLCONST     FORMATTED_LEX_ERROR
%%

formatted_string : formatted 

formatted   : atomic_formatted
            | struct_formatted
            | vector_formatted

atomic_formatted    : CHARCONST
                    | INTCONST 
                    | REALCONST
                    | STRCONST 
                    | BOOLCONST

struct_formatted :  '(' attr_list ')' 

attr_list   : attr ',' attr_list 
            | attr

attr : FORMATTED_LEX_ID  formatted 

vector_formatted : '[' formatted_list ']' 

formatted_list  : formatted ',' formatted_list 
                | formatted
%%

int yyerror(){
    fprintf(stderr, "Error while parsing the formatted values.\n");
    return -1;
}

void parse_formatted(FILE* stream){
    formattedin=stream;
    yyparse();
}

这是lex

%{
#include <stdlib.h>
...

Value lexval;
%}
%option noyywrap
spacing     ([ \t])+
eol         \n
letter      [a-zA-Z]
digit       [0-9]
id          {letter}({letter}|{digit})*:
num         {digit}+
sugar       [\(\)\[\]".":,;]
charconst   \'.\'
intconst    -?{num}
realconst   -?{num}?"."{num}
boolconst   (true|false)
stringconst \"([^\"])*\"

%%
{spacing}       ;
{eol}           return -1;
{boolconst}     {lexval.cval = (yytext[0] == 'f' ? '0' : '1'); return(BOOLCONST);}
{intconst}      {lexval.ival = atoi(yytext); return(INTCONST);}
{realconst}     {lexval.rval = atof(yytext); return(REALCONST);}
{charconst}     {lexval.ival = yytext[1]; return(CHARCONST);}
{stringconst}   {lexval.sval = insert_str_c(yytext); return(STRCONST);}
{sugar}         {return(yytext[0]);}
{id}            {yytext[strlen(yytext)-1]=0; lexval.sval = insert_str_c(yytext); return FORMATTED_LEX_ID;}
.               {return (FORMATTED_LEX_ERROR);}

问题是我们需要从文件或stdin解析它,调用parse_formatted(file_name)parse_formatted(stdin)

它似乎首先起作用,但是如果从文件中读取后跟stdin读取,则不再起作用......它似乎进入函数parse_formatted但是{{ 1}}无法识别任何内容。

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

如果前一个源实际到达文件结尾,则只能通过重新分配yyin来更改输入源。或者,更准确地说,当前输入缓冲区将继续被词法分析器使用,直到它耗尽,然后才能从输入源读取数据。为了丢弃当前输入缓冲区并切换输入源,您可以使用yyrestart(请参阅flex manual。)

或者,您可以在词法分析器操作中使用YY_FLUSH_BUFFER special action换行。

请参阅Bison FAQ&#34;如何重置解析器?&#34;与示例进行更长时间的讨论。