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 的语法错误。但也许我误解了你的错误报告。
我有以下用于词法和句法分析的文件:
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 的语法错误。但也许我误解了你的错误报告。