Парсер из разных потоков

Нам нужно проанализировать значение в соответствии с этой грамматикой:

%{
    ...
    #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();
}

это лекс

%{
#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);}

проблема в том, что нам нужно разобрать его из файла или из стандартного ввода, вызывая либо parse_formatted(file_name) или же parse_formatted(stdin)

Поначалу казалось, что это работает, но если есть чтение из файла, за которым следует чтение из стандартного ввода, это больше не работает... кажется, что он входит в функцию parse_formatted но yyparse ничего не узнает

Кто-нибудь может помочь?

1 ответ

Решение

Вы можете только изменить источники входного сигнала, переназначив yyin если предыдущий источник действительно достиг конца файла. Или, если быть более точным, текущий входной буфер будет продолжать использоваться лексером до тех пор, пока он не будет исчерпан, и только тогда данные будут считаны из входного источника. Чтобы отказаться от текущего входного буфера и переключить источники входного сигнала, вы можете использовать yyrestart (см. руководство по флексу.)

В качестве альтернативы, вы можете использовать YY_FLUSH_BUFFER специальное действие в вашем лексере для новой строки.

См. Bison FAQ "Как я могу сбросить парсер?" для более длительного обсуждения с примерами.

Другие вопросы по тегам