c - 来自不同流的解析器

标签 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);}

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

一开始似乎可以工作,但是如果先从文件读取,然后再从标准输入读取,则这不再工作......它似乎进入了函数 parse_formattedyyparse 无法识别任何内容。

有人可以帮忙吗?

最佳答案

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

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

请参阅Bison FAQ “如何重置解析器?”通过示例进行更长时间的讨论。

关于c - 来自不同流的解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24807659/

相关文章:

c - 为什么多了一个数字?

bison - Lex 和 Yacc 可以对自己进行 lex 和解析吗?

c++ - 用于任意编程语言或 IR 的 AST

c++ - 'YYSTYPE' 没有成员

c - Uft示例编译

比较 C 中的 SHA 校验和值

bison - 初学者 Bison 弯曲

bison - `debut' 的错误 $1 没有声明类型 Bison/Yacc

c++ - 转移/减少 Bison 的冲突

C动态加载文件太短?