Browse Source

Error messages from lexical and grammatical parsers now contains include stack.

ObjPtr
Michael Uleysky 9 years ago
parent
commit
eeeb74f2f4
  1. 7
      include/parser.h
  2. 1
      src/parser/grammatical.y
  3. 11
      src/parser/lexical.l

7
include/parser.h

@ -1,5 +1,6 @@
#ifndef PARSER_PARSER_H #ifndef PARSER_PARSER_H
#define PARSER_PARSER_H #define PARSER_PARSER_H
#include <list>
#include <stack> #include <stack>
#include <string> #include <string>
#include <stdio.h> #include <stdio.h>
@ -37,10 +38,16 @@ struct lexical_extra
// Bison location // Bison location
struct grammatic_location struct grammatic_location
{ {
struct incloc
{
int line,column;
std::string filename;
};
int first_line; int first_line;
int first_column; int first_column;
int last_line; int last_line;
int last_column; int last_column;
std::list<struct incloc> incstack;
std::string filename; std::string filename;
}; };

1
src/parser/grammatical.y

@ -31,6 +31,7 @@ inline void conferror(const YYLTYPE* locp, yyscan_t sc, const char* str)
COUT(ERROR)<<std::endl<<" Grammatical parser: "<<str<<std::endl<<" in file "<<locp->filename; COUT(ERROR)<<std::endl<<" Grammatical parser: "<<str<<std::endl<<" in file "<<locp->filename;
if(locp->first_line==locp->last_line) COUT(ERROR)<<" at line "<<locp->last_line<<", from position "<<locp->first_column<<" to "<<locp->last_column<<std::endl; if(locp->first_line==locp->last_line) COUT(ERROR)<<" at line "<<locp->last_line<<", from position "<<locp->first_column<<" to "<<locp->last_column<<std::endl;
else COUT(ERROR)<<" from line "<<locp->first_line<<", position "<<locp->first_column<<" to line "<<locp->last_line<<", position "<<locp->last_column<<std::endl; else COUT(ERROR)<<" from line "<<locp->first_line<<", position "<<locp->first_column<<" to line "<<locp->last_line<<", position "<<locp->last_column<<std::endl;
for(const auto &i:locp->incstack) COUT(ERROR)<<" included from "<<i.filename<<" at line "<<i.line<<", position "<<i.column<<std::endl;
} }
inline void conferror(const YYLTYPE& locp, yyscan_t sc, const std::string& str) inline void conferror(const YYLTYPE& locp, yyscan_t sc, const std::string& str)
{ {

11
src/parser/lexical.l

@ -31,7 +31,10 @@ class ObjectBase;
// Termination (mostly, in case of errors) // Termination (mostly, in case of errors)
#define yyterminate(ret) { while(0!=YY_CURRENT_BUFFER) yypop_buffer_state(yyscanner); str.erase(); yyextra->retcode=-(ret); return (ret); } #define yyterminate(ret) { while(0!=YY_CURRENT_BUFFER) yypop_buffer_state(yyscanner); str.erase(); yyextra->retcode=-(ret); return (ret); }
// Abnormal termination with description of error // Abnormal termination with description of error
#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 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;\
for(const auto &i:yylloc_param->incstack) COUT(ERROR)<<" included from "<<i.filename<<" at line "<<i.line<<", position "<<i.column<<std::endl;\
yyterminate(ret);}
// Trace position // Trace position
#define yynextline {yyextra->state.curline++; yyextra->state.curpos=0; yyextra->state.curoffset++;} #define yynextline {yyextra->state.curline++; yyextra->state.curpos=0; yyextra->state.curoffset++;}
#define yynextsym {yyextra->state.curpos+=yyleng; yyextra->state.curoffset+=yyleng;} #define yynextsym {yyextra->state.curpos+=yyleng; yyextra->state.curoffset+=yyleng;}
@ -39,10 +42,11 @@ class ObjectBase;
#define setyyllocp {yylloc_param->first_line=yylloc_param->last_line=yyextra->state.curline; yylloc_param->first_column=yyextra->state.curpos; yylloc_param->last_column=yylloc_param->first_column+yyleng;} #define setyyllocp {yylloc_param->first_line=yylloc_param->last_line=yyextra->state.curline; yylloc_param->first_column=yyextra->state.curpos; yylloc_param->last_column=yylloc_param->first_column+yyleng;}
std::string str; std::string str;
int incpos,incline;
%} %}
%% %%
<PARSE,INITIAL>@[Ii][Nn][Cc][Ll][Uu][Dd][Ee][ \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(); incpos=yyextra->state.curpos; incline=yyextra->state.curline; yynextsym;
@ BEGIN(PREPROC); yynextsym; @ BEGIN(PREPROC); yynextsym;
<PREPROC>[a-zA-Z]* { <PREPROC>[a-zA-Z]* {
yynextsym; str=yytext; tolower(str); yynextsym; str=yytext; tolower(str);
@ -84,6 +88,7 @@ std::string str;
} }
if(0==fd) yyerrormessage("can't open file "+str,-1); if(0==fd) yyerrormessage("can't open file "+str,-1);
yylloc_param->incstack.push_front({incline,incpos,yylloc_param->filename});
yynextsym; yynextsym;
yyextra->fds.push(fd); yyextra->fds.push(fd);
yyextra->states.push(yyextra->state); yyextra->states.push(yyextra->state);
@ -137,5 +142,5 @@ std::string str;
<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>\" 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; yylloc_param->incstack.pop_front();} else yyterminate(0);
%% %%

Loading…
Cancel
Save