Reputation: 3
I have the following files for lexical and syntactic analysis:
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 << *$2 << ": " << *$4 << endl;
a_minus(*$2);
opc[*$2] = *$4;
delete $4;
};
fit: GUION FIT IGUAL VFIT{
cout << *$2 << ": " << *$4 << endl;
a_minus(*$2);
a_minus(*$4);
opc[*$2] = *$4; delete $4;
};
unit: GUION UNIT IGUAL VUNIT{
cout << *$2 << ": " << *$4 << endl;
a_minus(*$2);
a_minus(*$4);
opc[*$2] = *$4; delete $4;
};
path: GUION PATH IGUAL val_path{
cout << *$2 << ": " << *$4 << endl;
a_minus(*$2);
opc[*$2] = *$4; delete $4;
};
val_path: VSTRING;
%%
The following entry must be correct: mkdisk -size=20. The code for the size rule runs, however, in order for the code for the instr rule to run I have to press CTRL + D. Why does that happen? What is missing to add to the code? Is the parser lexical or syntactic?
EDIT: I removed the EOL token from the parser. What I don't really understand is, how does the parser know that the entry has finished? After entering the mkdisk -size = 20 command in the console, press the ENTER key. How do I tell Bison that my entry ends with ENTER? Why does the analyzer wait for an entry to finish the analysis?
Upvotes: 0
Views: 110
Reputation: 241791
It says here:
mkdisk: MKDISK list_mkdisk EOL;
So mkdisk
needs an EOL
token in order to be complete, and it won't be reduced until it's complete.
But nowhere does your lexer return an EOL
token. Assuming that EOL
means "end of line", it would be logical for \n
to produce an EOL
token. But we have
[ \t\n] { /* Ignorar espacios en blanco */ }
So no EOL token, and no reduction. I don't see any way that the instr
rule could run; if you enter an EOF, then the parser should report a syntax error from the missing EOL. But maybe I'm misunderstanding your error report.
Upvotes: 1