@ -2,7 +2,6 @@
%option warn
%option warn
%option yylineno
%option yylineno
%option noyywrap
%option noyywrap
%option yylineno
%option header-file="lexical.h"
%option header-file="lexical.h"
%option outfile="lexical.cpp"
%option outfile="lexical.cpp"
%option prefix="conf"
%option prefix="conf"
@ -10,66 +9,87 @@
%option bison-bridge
%option bison-bridge
%option bison-locations
%option bison-locations
%option nounput
%option nounput
%option stack
%x PSTRING
%x PSTRING
%x PARSE
%x PARSE
%x INCLUDE
%{
%{
#if __cplusplus > 199711L
#if __cplusplus > 199711L
#define register // Deprecated in C++11.
#define register // Deprecated in C++11.
#endif // #if __cplusplus > 199711L
#endif // #if __cplusplus > 199711L
#include <stdlib.h>
#include <stdlib.h>
#include <string>
#include "../debug.h"
#include "../debug.h"
#include "../object.h"
#include "../object.h"
#include "parser.h"
#include "parser.h"
#include "grammatical.h"
#include "grammatical.h"
// Get rid of warning on unneed ed function
// Get rid of warning on unus ed function
#define YY_NO_INPUT
#define YY_NO_INPUT
static std::string str;
// definitions for bison-bridge
#define YYSTYPE CONFSTYPE
#define YYLTYPE CONFLTYPE
std::string str;
#define yyterminate(ret) { while(YY_CURRENT_BUFFER) yypop_buffer_state(yyscanner); str.erase(); yyextra->retcode=-(ret); return (ret); }
#define yyerrormessage(message,ret) {COUT(ERROR)<<std::endl<<" Lexical error in file "<<yyextra->state.curdir<<yyextra->state.filename<<" at line "<<yyextra->state.curline<<": "<<(message)<<std::endl; yyterminate(ret);}
#define yynextline {yyextra->state.curline++; yyextra->state.curpos=0; yyextra->state.curoffset++;}
#define yynextsym {yyextra->state.curpos+=yyleng; yyextra->state.curoffset+=yyleng;}
%}
%}
%%
%%
<PARSE,INITIAL,PSTRING>\n yyextra->curline++; yyextra->curpos=0; yyextra->curoffset++; REJECT;
<PARSE,INITIAL>@include[ \t]*\" yy_push_state(INCLUDE,yyscanner); str.erase(); yynextsym;
<PARSE,INITIAL,PSTRING>. yyextra->curpos++; yyextra->curoffset++; REJECT;
<INCLUDE>\" {
include\(\".+\"\); {/*
if(yyextra->state.inclevel>=yyextra->maxinclevel) yyerrormessage("maximal include level reached",-1);
if(yyextra->inclevel>=yyextra->maxinclevel) { COUT(ERROR)<<"Max include level reached in file "<<yyextra->filename<<" at line "<<yylineno<<std::endl; return 1; }
yyscan_t scanner;
struct lexical_extra extra;
std::string fname(yytext+9,yyleng-12);
FILE* fd;
FILE* fd;
fd=fopen(fname.c_str(),"r");
if(fd==0) { COUT(ERROR)<<"Can't open file "<<fname<<std::endl; return -1; }
COUT(DEBUG)<<"Include "<<fname<<std::endl;
extra.filename=fname.c_str();
extra.inclevel=yyextra->inclevel+1;
extra.maxinclevel=yyextra->maxinclevel;
yylex_init_extra(&extra,&scanner);
yyset_in(fd,scanner);
yylex(scanner);
yylex_destroy(scanner);
fclose(fd);
*/}
// yyextra->curdir is directory with currently scanned file
[a-zA-Z][a-zA-Z0-9_]* COUT(MOREDEBUG)<<"NAME("<<yytext<<")"; BEGIN(PARSE); yylval_param->str=new std::string(yytext); return NAME;
// !!!NONPORTABLE!!!
<PARSE>[+\-*/^] COUT(MOREDEBUG)<<" OPERATION("<<yytext<<")"; return yytext[0];
if('/'==str[0]) fd=fopen(str.c_str(),"r"); // absolute path
<PARSE>[0-9]+ COUT(MOREDEBUG)<<" INTEGER("<<yytext<<")"; yylval_param->i=atoll(yytext); return INTEGER;
else
<PARSE>[0-9]+(\.[0-9]*)?([eE][+-][0-9]+)? COUT(MOREDEBUG)<<" REAL("<<yytext<<")"; yylval_param->r=atof(yytext); return REAL;
{
<PARSE>[TF] COUT(MOREDEBUG)<<" BOOL("<<yytext<<")"; yylval_param->b=(yytext[0]=='T')?true:false; return BOOL;
// first, try to search file in working directory
<PARSE>\( COUT(MOREDEBUG)<<" OBRACE()"; return OBRACE;
fd=fopen(str.c_str(),"r");
<PARSE>\) COUT(MOREDEBUG)<<" CBRACE()"; return CBRACE;
// if fail, try to search in directory with currently scanned file
<PARSE>\; COUT(MOREDEBUG)<<" ENDL()"<<std::endl; BEGIN(0); return ENDL;
if(fd==0) fd=fopen((yyextra->state.curdir+str).c_str(),"r");
<PARSE>= COUT(MOREDEBUG)<<" ASSIGN()"; return ASSIGN;
}
<PARSE>, COUT(MOREDEBUG)<<" DELIM()"; return DELIM;
<PARSE>[a-zA-Z][a-zA-Z0-9_]* COUT(MOREDEBUG)<<" IDENTIFIER("<<yytext<<")"; yylval_param->str=new std::string(yytext); return IDENTIFIER;
if(fd==0) yyerrormessage("can't open file "+str,-1);
<PARSE>\. COUT(MOREDEBUG)<<" DOT()"; return yytext[0];
yynextsym;
<PARSE,INITIAL>[ \n\t]
yyextra->fds.push(fd);
<PARSE,INITIAL>\#.*
yyextra->states.push(yyextra->state);
<PARSE>\" BEGIN(PSTRING); str.erase();
COUT(DEBUG)<<std::endl<<"Include "<<str<<std::endl;
<PARSE,INITIAL>. COUT(ERROR)<<"Unknown symbol "<<yytext<<" in file "<<yyextra->filename<<" at line "<<yylineno<<std::endl; yyterminate(); return -1;
<PSTRING>\\\\ str+='\\';
yyextra->state.inclevel++;
<PSTRING>\\\" str+='\"';
yyextra->ParsePath(str);
<PSTRING>\" BEGIN(PARSE); COUT(MOREDEBUG)<<" STRING("<<str<<")"; yylval_param->str=&str; return STRING;
yyextra->state.curline=1;
<PSTRING>. str+=yytext[0];
yyextra->state.curpos=yyextra->state.curoffset=0;
<PSTRING><<EOF>> COUT(ERROR)<<"Unclosed quote!"<<std::endl; str.erase(); yyterminate(); return -1;
<<EOF>> str.erase(); yyterminate(); return 0;
yypush_buffer_state(yy_create_buffer(fd,YY_BUF_SIZE,yyscanner),yyscanner);
// Get rid of warning on unused function
if(__builtin_expect(yy_top_state(yyscanner)==PSTRING,0)) yyerrormessage("misterious error",-1);
yy_pop_state(yyscanner);
}
[a-zA-Z][a-zA-Z0-9_]* COUT(MOREDEBUG)<<"NAME("<<yytext<<")"; BEGIN(PARSE); yylval_param->str=new std::string(yytext); yynextsym; return NAME;
<PARSE>[+\-*/^] COUT(MOREDEBUG)<<" OPERATION("<<yytext<<")"; return yytext[0]; yynextsym;
<PARSE>[0-9]+ COUT(MOREDEBUG)<<" INTEGER("<<yytext<<")"; yylval_param->i=atoll(yytext); yynextsym; return INTEGER;
<PARSE>[0-9]+(\.[0-9]*)?([eE][+-][0-9]+)? COUT(MOREDEBUG)<<" REAL("<<yytext<<")"; yylval_param->r=atof(yytext); yynextsym; return REAL;
<PARSE>[TF] COUT(MOREDEBUG)<<" BOOL("<<yytext<<")"; yylval_param->b=(yytext[0]=='T')?true:false; yynextsym; return BOOL;
<PARSE>\( COUT(MOREDEBUG)<<" OBRACE()"; yynextsym; return OBRACE;
<PARSE>\) COUT(MOREDEBUG)<<" CBRACE()"; yynextsym; return CBRACE;
<PARSE>\; COUT(MOREDEBUG)<<" ENDL()"<<std::endl; BEGIN(0); yynextsym; return ENDL;
<PARSE>= COUT(MOREDEBUG)<<" ASSIGN()"; yynextsym; return ASSIGN;
<PARSE>, COUT(MOREDEBUG)<<" DELIM()"; yynextsym; return DELIM;
<PARSE>[a-zA-Z][a-zA-Z0-9_]* COUT(MOREDEBUG)<<" IDENTIFIER("<<yytext<<")"; yylval_param->str=new std::string(yytext); yynextsym; return IDENTIFIER;
<PARSE>\. COUT(MOREDEBUG)<<" DOT()"; yynextsym; return yytext[0];
<PARSE,INITIAL>[ \t]+ yynextsym;
<PARSE,INITIAL>\n yynextline;
<PARSE,INITIAL>\#.* yynextsym;
<PARSE>\" BEGIN(PSTRING); str.erase(); yynextsym;
<PARSE,INITIAL>. yyerrormessage(std::string("unknown symbol ")+yytext+" at position "+std::to_string(yyextra->state.curpos),-1);
<PSTRING,INCLUDE>\\\\ str+='\\'; yynextsym;
<PSTRING,INCLUDE>\\\" str+='\"'; yynextsym;
<PSTRING>\n str+=yytext[0]; yynextline;
<PSTRING>\" BEGIN(PARSE); COUT(MOREDEBUG)<<" STRING("<<str<<")"; yylval_param->str=new std::string(str); yynextsym; return STRING;
<PSTRING,INCLUDE>. str+=yytext[0]; yynextsym;
<PSTRING,INCLUDE><<EOF>> yyerrormessage("unclosed quote",-1);
<<EOF>> yypop_buffer_state(yyscanner); if(YY_CURRENT_BUFFER) {yyextra->state=yyextra->states.top(); yyextra->states.pop(); fclose(yyextra->fds.top()); yyextra->fds.pop();} else yyterminate(0);
%%
%%