|
|
@ -13,8 +13,10 @@ |
|
|
|
%x PSTRING |
|
|
|
%x PSTRING |
|
|
|
%x PARSE |
|
|
|
%x PARSE |
|
|
|
%x INCLUDE |
|
|
|
%x INCLUDE |
|
|
|
|
|
|
|
%x PREPROC |
|
|
|
|
|
|
|
|
|
|
|
%{ |
|
|
|
%{ |
|
|
|
|
|
|
|
#include <algorithm> |
|
|
|
#include "common.h" |
|
|
|
#include "common.h" |
|
|
|
#include "parser.h" |
|
|
|
#include "parser.h" |
|
|
|
// flex use register keyword, but it deprecated in C++11. |
|
|
|
// flex use register keyword, but it deprecated in C++11. |
|
|
@ -41,30 +43,55 @@ std::string str; |
|
|
|
%} |
|
|
|
%} |
|
|
|
|
|
|
|
|
|
|
|
%% |
|
|
|
%% |
|
|
|
<PARSE,INITIAL>@include[ \t]*\" yy_push_state(INCLUDE,yyscanner); str.erase(); yynextsym; |
|
|
|
<PARSE,INITIAL>@[Ii][Nn][Cc][Ll][Uu][Dd][Ee][ \t]*\" yy_push_state(INCLUDE,yyscanner); str.erase(); yynextsym; |
|
|
|
|
|
|
|
@ BEGIN(PREPROC); yynextsym; |
|
|
|
|
|
|
|
<PREPROC>[a-zA-Z]* { |
|
|
|
|
|
|
|
yynextsym; str=yytext; transform(str.begin(),str.end(),str.begin(),::tolower); |
|
|
|
|
|
|
|
if("use"==str) return DIR_USE; |
|
|
|
|
|
|
|
if("includepath"==str) return DIR_INCLUDEPATH; |
|
|
|
|
|
|
|
if("modulepath"==str) return DIR_MODULEPATH; |
|
|
|
|
|
|
|
if("as"==str) return DIR_AS; |
|
|
|
|
|
|
|
COUT(WARNING)<<std::endl<<"Unknown directive "<<str<<", ignoring"<<std::endl; |
|
|
|
|
|
|
|
} |
|
|
|
<INCLUDE>\" { |
|
|
|
<INCLUDE>\" { |
|
|
|
if(yyextra->state.inclevel>=yyextra->maxinclevel) yyerrormessage("maximal include level reached",-1); |
|
|
|
if(yyextra->state.inclevel>=yyextra->maxinclevel) yyerrormessage("maximal include level reached",-1); |
|
|
|
FILE* fd; |
|
|
|
FILE* fd; |
|
|
|
|
|
|
|
std::string fullname; |
|
|
|
|
|
|
|
|
|
|
|
// yyextra->curdir is directory with currently scanned file |
|
|
|
// yyextra->curdir is directory with currently scanned file |
|
|
|
// !!!NONPORTABLE!!! |
|
|
|
// !!!NONPORTABLE!!! |
|
|
|
if('/'==str[0]) fd=fopen(str.c_str(),"r"); // absolute path |
|
|
|
fullname=str; |
|
|
|
|
|
|
|
if('/'==fullname[0]) fd=fopen(fullname.c_str(),"r"); // absolute path |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
// first, try to search file in working directory |
|
|
|
// first, try to search in directory with currently scanned file |
|
|
|
fd=fopen(str.c_str(),"r"); |
|
|
|
fullname=yyextra->state.curdir+str; |
|
|
|
// if fail, try to search in directory with currently scanned file |
|
|
|
fd=fopen(fullname.c_str(),"r"); |
|
|
|
if(fd==0) fd=fopen((yyextra->state.curdir+str).c_str(),"r"); |
|
|
|
// if fail, try to search file in includedirs |
|
|
|
|
|
|
|
if(0==fd) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::string curpath; |
|
|
|
|
|
|
|
size_t bpos=0,epos; |
|
|
|
|
|
|
|
do |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
epos=yyextra->includedirs.find(':',bpos); |
|
|
|
|
|
|
|
curpath=yyextra->includedirs.substr(bpos,(std::string::npos==epos)?epos:(epos-bpos)); |
|
|
|
|
|
|
|
fullname=curpath+str; |
|
|
|
|
|
|
|
fd=fopen(fullname.c_str(),"r"); |
|
|
|
|
|
|
|
if(0!=fd) break; |
|
|
|
|
|
|
|
bpos=epos+1; |
|
|
|
|
|
|
|
} while(std::string::npos!=epos); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(fd==0) yyerrormessage("can't open file "+str,-1); |
|
|
|
if(0==fd) yyerrormessage("can't open file "+str,-1); |
|
|
|
yynextsym; |
|
|
|
yynextsym; |
|
|
|
yyextra->fds.push(fd); |
|
|
|
yyextra->fds.push(fd); |
|
|
|
yyextra->states.push(yyextra->state); |
|
|
|
yyextra->states.push(yyextra->state); |
|
|
|
COUT(DEBUG)<<std::endl<<"Include "<<str<<std::endl; |
|
|
|
COUT(DEBUG)<<std::endl<<"Include "<<str<<std::endl; |
|
|
|
|
|
|
|
|
|
|
|
yyextra->state.inclevel++; |
|
|
|
yyextra->state.inclevel++; |
|
|
|
yyextra->ParsePath(str); |
|
|
|
yyextra->ParsePath(fullname); |
|
|
|
yyextra->state.curline=1; |
|
|
|
yyextra->state.curline=1; |
|
|
|
yyextra->state.curpos=yyextra->state.curoffset=0; |
|
|
|
yyextra->state.curpos=yyextra->state.curoffset=0; |
|
|
|
yylloc_param->filename=yyextra->state.curdir+yyextra->state.filename; |
|
|
|
yylloc_param->filename=yyextra->state.curdir+yyextra->state.filename; |
|
|
@ -86,15 +113,16 @@ std::string str; |
|
|
|
<PARSE>, COUT(MOREDEBUG)<<" DELIM()"; setyyllocp; yynextsym; return DELIM; |
|
|
|
<PARSE>, COUT(MOREDEBUG)<<" DELIM()"; setyyllocp; yynextsym; return DELIM; |
|
|
|
<PARSE>[a-zA-Z][a-zA-Z0-9_]* COUT(MOREDEBUG)<<" IDENTIFIER("<<yytext<<")"; yylval_param->str=new std::string(yytext); setyyllocp; yynextsym; return IDENTIFIER; |
|
|
|
<PARSE>[a-zA-Z][a-zA-Z0-9_]* COUT(MOREDEBUG)<<" IDENTIFIER("<<yytext<<")"; yylval_param->str=new std::string(yytext); setyyllocp; yynextsym; return IDENTIFIER; |
|
|
|
<PARSE>\. COUT(MOREDEBUG)<<" DOT()"; setyyllocp; yynextsym; return yytext[0]; |
|
|
|
<PARSE>\. COUT(MOREDEBUG)<<" DOT()"; setyyllocp; yynextsym; return yytext[0]; |
|
|
|
<PARSE,INITIAL>[ \t]+ yynextsym; |
|
|
|
<PARSE,PREPROC,INITIAL>[ \t]+ yynextsym; |
|
|
|
<PARSE,INITIAL>\n yynextline; |
|
|
|
<PARSE,INITIAL>\n yynextline; |
|
|
|
|
|
|
|
<PREPROC>\n BEGIN(0); yynextline; |
|
|
|
<PARSE,INITIAL>\#.* yynextsym; |
|
|
|
<PARSE,INITIAL>\#.* yynextsym; |
|
|
|
<PARSE>\" BEGIN(PSTRING); str.erase(); yyextra->states.push(yyextra->state); yynextsym; |
|
|
|
<PARSE,PREPROC>\" yy_push_state(PSTRING,yyscanner); str.erase(); yyextra->states.push(yyextra->state); yynextsym; |
|
|
|
<PARSE,INITIAL>. yyerrormessage(std::string("unknown symbol ")+yytext+" at position "+std::to_string(yyextra->state.curpos),-1); |
|
|
|
<PARSE,PREPROC,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,INCLUDE>\\\" str+='\"'; yynextsym; |
|
|
|
<PSTRING,INCLUDE>\\\" str+='\"'; yynextsym; |
|
|
|
<PSTRING>\n str+=yytext[0]; yynextline; |
|
|
|
<PSTRING>\n str+=yytext[0]; yynextline; |
|
|
|
<PSTRING>\" BEGIN(PARSE); COUT(MOREDEBUG)<<" STRING("<<str<<")"; yylval_param->str=new std::string(str); {struct lexical_state prstate=yyextra->states.top(); yyextra->states.pop(); yylloc_param->first_line=prstate.curline; yylloc_param->last_line=yyextra->state.curline; yylloc_param->first_column=prstate.curpos; yylloc_param->last_column=yyextra->state.curpos+yyleng;}; yynextsym; return STRING; |
|
|
|
<PSTRING>\" yy_pop_state(yyscanner); COUT(MOREDEBUG)<<" STRING("<<str<<")"; yylval_param->str=new std::string(str); {struct lexical_state prstate=yyextra->states.top(); yyextra->states.pop(); yylloc_param->first_line=prstate.curline; yylloc_param->last_line=yyextra->state.curline; yylloc_param->first_column=prstate.curpos; yylloc_param->last_column=yyextra->state.curpos+yyleng;}; yynextsym; return STRING; |
|
|
|
<PSTRING,INCLUDE>. str+=yytext[0]; yynextsym; |
|
|
|
<PSTRING,INCLUDE>. str+=yytext[0]; yynextsym; |
|
|
|
<PSTRING,INCLUDE><<EOF>> yyextra->states.pop(); yyerrormessage("unclosed quote",-1); |
|
|
|
<PSTRING,INCLUDE><<EOF>> yyextra->states.pop(); yyerrormessage("unclosed quote",-1); |
|
|
|
<<EOF>> yypop_buffer_state(yyscanner); if(0!=YY_CURRENT_BUFFER) {yyextra->state=yyextra->states.top(); yyextra->states.pop(); fclose(yyextra->fds.top()); yyextra->fds.pop(); yylloc_param->filename=yyextra->state.curdir+yyextra->state.filename;} else yyterminate(0); |
|
|
|
<<EOF>> yypop_buffer_state(yyscanner); if(0!=YY_CURRENT_BUFFER) {yyextra->state=yyextra->states.top(); yyextra->states.pop(); fclose(yyextra->fds.top()); yyextra->fds.pop(); yylloc_param->filename=yyextra->state.curdir+yyextra->state.filename;} else yyterminate(0); |
|
|
|