Парсер из разных потоков
Нам нужно проанализировать значение в соответствии с этой грамматикой:
%{
...
#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 "Как я могу сбросить парсер?" для более длительного обсуждения с примерами.