Bison/flex识别规则后等待输入

Bison/flex waits for input after recognizing a rule

我有以下用于词法和句法分析的文件:

lexico.l

%{
    #include <iostream>
    #include <stdio.h>
    #include <string>   
    using namespace std;
    extern int yylex();
    #include "sintactico.h" // to get token types from Bison
%}
%option noyywrap
vfit1                       (?i:ff)
vfit2                       (?i:bf)
vfit3                       (?i:wf)
%%
#(.)*                       { printf("COMENTARIO\n"); }
[ \t\n]                     { /* Ignorar espacios en blanco */ }
[0-9]+                      { printf("INT\n"); yylval.sval = new string(yytext); return INT; }
\"([^\\"]|\.)*\"          { printf("STRING\n"); /*return STRING*/ }
(?i:mkdisk)                 { printf("MKDISK\n"); return MKDISK; }
(?i:size)                   { printf("SIZE\n");  yylval.sval = new string(yytext); return SIZE; }
(?i:unit)                   { printf("UNIT\n");  yylval.sval = new string(yytext); return UNIT; }
(?i:path)                   { printf("PATH\n");  yylval.sval = new string(yytext); return PATH; }
(?i:fit)                    { printf("FIT\n");  yylval.sval = new string(yytext); return FIT; }
-                           { printf("GUION\n"); return GUION; }
=                           { printf("IGUAL\n"); return IGUAL; }
{vfit1}|{vfit2}|{vfit3}     { printf("VFIT\n");  yylval.sval = new string(yytext); return VFIT; }
[bkmKBM]                    { printf("VUNIT\n"); yylval.sval = new string(yytext); return VUNIT; }
[a-zA-Z0-9/._]+             { printf("VSTRING\n"); yylval.sval = new string(yytext); return VSTRING; }
.                           { printf("ERROR\n"); }
%%

sintactico.y

%{  
    #include <cstdio>   
    #include <cstdlib>
    #include <string>
    #include <iostream>
    #include <map>
    using namespace std;
    map<string, string> opc;
    // Declare stuff from Flex that Bison needs to know about:
    extern int yylex();
    //extern int yyparse();
    extern FILE *yyin;
    #include "lexico.h"
    #include "cadena.h"

    void yyerror(const char *s);

    void test_map(){        
        cout << "opc.size() is " << opc.size() << endl;
        for(auto it : opc){
            cout << "*************************\n";
            cout << it.first << endl;
            cout << it.second << endl;
            cout << "*************************\n";
        }
    }       
%}

%union{
    int ival;       
    char cval;
    std::string *sval;  
}

%token        MKDISK RMDISK FDISK MOUNT UNMOUNT 
%token        TYPE DELETE 
%token        NAME ADD ID STRING GUION IGUAL

%token <sval> SIZE FIT PATH UNIT 
%token <sval> VSTRING INT VFIT VUNIT

%type <sval>  val_path

%%

axioma:             instr{
                        cout << "Finaliza" << endl;
                    };  

instr:              mkdisk{
                        analisis_mkdisk(opc);
                    };

mkdisk:             MKDISK list_mkdisk;

list_mkdisk:        list_mkdisk opc_mkdisk
                |   opc_mkdisk;

opc_mkdisk:         size
                |   fit
                |   unit
                |   path;

size:               GUION SIZE IGUAL INT{
                        cout << * << ": " << * << endl;
                        a_minus(*);                   
                        opc[*] = *;
                        delete ;                      
                    };

fit:                GUION FIT IGUAL VFIT{
                        cout << * << ": " << * << endl;
                        a_minus(*); 
                        a_minus(*);
                        opc[*] = *; delete ;
                    };

unit:               GUION UNIT IGUAL VUNIT{
                        cout << * << ": " << * << endl;
                        a_minus(*);
                        a_minus(*);
                        opc[*] = *; delete ;
                    };

path:               GUION PATH IGUAL val_path{
                        cout << * << ": " << * << endl;
                        a_minus(*);
                        opc[*] = *; delete ;
                    };

val_path:           VSTRING;                

%%

以下条目必须正确:mkdisk -size=20。大小规则的代码 运行s,但是,为了使 instr 规则的代码为 运行,我必须按 CTRL + D。为什么会这样?添加到代码中缺少什么?解析器是词法的还是句法的?

编辑:我从解析器中删除了 EOL 令牌。 我不太明白的是,解析器如何知道条目已经完成?在控制台输入mkdisk -size = 20 命令后,按回车键。我如何告诉 Bison 我的条目以 ENTER 结束?为什么分析器要等一个入口才能完成分析?

这里说:

mkdisk:             MKDISK list_mkdisk EOL;

所以mkdisk需要一个EOL令牌才能完成,并且在完成之前不会减少。

但是您的词法分析器 return 没有 EOL 标记。假设 EOL 表示 "end of line",\n 产生一个 EOL 标记是合乎逻辑的。但是我们有

[ \t\n]                     { /* Ignorar espacios en blanco */ }

所以没有 EOL 令牌,也没有减少。我看不出 instr 规则可以 运行;如果您输入 EOF,那么解析器应该报告缺少 EOL 的语法错误。但也许我误解了你的错误报告。