Support line directives from the preprocessor.
This commit is contained in:
parent
954b42b66b
commit
4939e9fe61
|
|
@ -22,7 +22,7 @@ THE IVL PREPROCESSOR
|
|||
The ivlpp command is a verilog preprocessor that handles file
|
||||
inclusion and macro substitution. The program runs separate from the
|
||||
actual compiler so as to ease the task of the compiler proper, and
|
||||
provide a means of preprocessing files off-line.
|
||||
provides a means of preprocessing files off-line.
|
||||
|
||||
|
||||
USAGE:
|
||||
|
|
@ -49,10 +49,10 @@ valid options include:
|
|||
flags as needed.
|
||||
|
||||
-L
|
||||
Add to the output #line directives. The ivl compiler
|
||||
understands these directives and uses them to keep track
|
||||
of the current line of the original source file. This
|
||||
makes error messages more meaningful.
|
||||
Generate #line directives. The ivl compiler understands
|
||||
these directives and uses them to keep track of the
|
||||
current line of the original source file. This makes error
|
||||
messages more meaningful.
|
||||
|
||||
-o <file>
|
||||
Send the output to the named file, instead of to standard
|
||||
|
|
@ -76,3 +76,30 @@ directories in the order that the -I flag appears.
|
|||
The exception to this process is include files that have a name that
|
||||
starts with the '/' character. These file names are ``rooted names''
|
||||
and must be in the rooted location specified.
|
||||
|
||||
|
||||
GENERATED LINE DIRECTIVES
|
||||
|
||||
Compilers generally try to print along with their error messages the
|
||||
file and line number where the error occurred. Icarus Verilog is no
|
||||
exception. However, if a separate preprocessor is actually selecting
|
||||
and opening files, then the line numbers counted by the compiler
|
||||
proper will not reflect the actual line numbers in the source file.
|
||||
|
||||
To handle this situation, the preprocessor can generate line
|
||||
directives. These directives are lines of the form:
|
||||
|
||||
#line <name> <num>
|
||||
|
||||
where <name> is the file name in double-quotes and <num> is the line
|
||||
number in the file. The parser changes the filename and line number
|
||||
counters in such a way that the next line is line number <num>+1 in
|
||||
the file named <name>. For example:
|
||||
|
||||
#line "foo.vl" 5
|
||||
// I am on line 6 in file foo.vl.
|
||||
|
||||
The preprocessor generates a #line directive every time it switches
|
||||
files. That includes starting an included file (#line "foo.vlh" 0) or
|
||||
returning to the including file.
|
||||
|
||||
|
|
|
|||
105
lexor.lex
105
lexor.lex
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1998 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: lexor.lex,v 1.27 1999/06/22 03:59:37 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.28 1999/07/03 21:27:22 steve Exp $"
|
||||
#endif
|
||||
|
||||
//# define YYSTYPE lexval
|
||||
|
|
@ -38,9 +38,9 @@ extern string vl_file;
|
|||
extern YYLTYPE yylloc;
|
||||
|
||||
static void reset_lexor();
|
||||
static void line_directive();
|
||||
|
||||
static int check_identifier(const char*name);
|
||||
static void ppinclude_filename();
|
||||
static void ppdo_include();
|
||||
static verinum*make_sized_binary(const char*txt);
|
||||
static verinum*make_sized_dec(const char*txt);
|
||||
static verinum*make_unsized_dec(const char*txt);
|
||||
|
|
@ -58,11 +58,12 @@ static int comment_enter;
|
|||
%x LCOMMENT
|
||||
%x CSTRING
|
||||
%s UDPTABLE
|
||||
%x PPINCLUDE
|
||||
%x PPTIMESCALE
|
||||
|
||||
%%
|
||||
|
||||
^"#line"[ ]+\"[^\"]*\"[ ]+[0-9]+.* { line_directive(); }
|
||||
|
||||
[ \t\b\f\r] { ; }
|
||||
\n { yylloc.first_line += 1; }
|
||||
|
||||
|
|
@ -210,19 +211,6 @@ static int comment_enter;
|
|||
yylloc.first_line += 1;
|
||||
BEGIN(0); }
|
||||
|
||||
`include {
|
||||
BEGIN(PPINCLUDE); }
|
||||
|
||||
<PPINCLUDE>\"[^\"]*\" {
|
||||
ppinclude_filename(); }
|
||||
|
||||
<PPINCLUDE>[ \t\b\f\r] { ; }
|
||||
|
||||
<PPINCLUDE>\n {
|
||||
BEGIN(0);
|
||||
yylloc.first_line += 1;
|
||||
ppdo_include(); }
|
||||
|
||||
|
||||
. { cerr << yylloc.first_line << ": unmatched character (";
|
||||
if (isgraph(yytext[0]))
|
||||
|
|
@ -769,71 +757,40 @@ static verinum*make_unsized_dec(const char*txt)
|
|||
return make_dec_with_size(INTEGER_WIDTH, false, txt+1);
|
||||
}
|
||||
|
||||
struct include_stack_t {
|
||||
string path;
|
||||
FILE*file;
|
||||
unsigned lineno;
|
||||
YY_BUFFER_STATE yybs;
|
||||
|
||||
struct include_stack_t*next;
|
||||
};
|
||||
|
||||
static include_stack_t*include_stack = 0;
|
||||
|
||||
static string ppinclude_path;
|
||||
|
||||
static void ppinclude_filename()
|
||||
{
|
||||
ppinclude_path = yytext+1;
|
||||
ppinclude_path = ppinclude_path.substr(0, ppinclude_path.length()-1);
|
||||
}
|
||||
|
||||
static void ppdo_include()
|
||||
{
|
||||
FILE*file = fopen(ppinclude_path.c_str(), "r");
|
||||
if (file == 0) {
|
||||
cerr << ppinclude_path << ": Unable to open include file." << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
include_stack_t*isp = new include_stack_t;
|
||||
isp->path = vl_file;
|
||||
isp->file = vl_input;
|
||||
isp->lineno = yylloc.first_line;
|
||||
isp->next = include_stack;
|
||||
isp->yybs = YY_CURRENT_BUFFER;
|
||||
|
||||
vl_file = ppinclude_path;
|
||||
vl_input = file;
|
||||
yylloc.first_line = 1;
|
||||
yylloc.text = vl_file.c_str();
|
||||
yy_switch_to_buffer(yy_new_buffer(vl_input, YY_BUF_SIZE));
|
||||
include_stack = isp;
|
||||
}
|
||||
|
||||
static int yywrap()
|
||||
{
|
||||
include_stack_t*isp = include_stack;
|
||||
if (isp == 0)
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
yy_delete_buffer(YY_CURRENT_BUFFER);
|
||||
fclose(vl_input);
|
||||
/*
|
||||
* The line directive matches lines of the form #line "foo" N and
|
||||
* calls this function. Here I parse out the file name and line
|
||||
* number, and change the yylloc to suite.
|
||||
*/
|
||||
static void line_directive()
|
||||
{
|
||||
char*qt1 = strchr(yytext, '"');
|
||||
assert(qt1);
|
||||
qt1 += 1;
|
||||
|
||||
vl_input = isp->file;
|
||||
vl_file = isp->path;
|
||||
yy_switch_to_buffer(isp->yybs);
|
||||
yylloc.first_line = isp->lineno;
|
||||
yylloc.text = vl_file.c_str();
|
||||
include_stack = isp->next;
|
||||
delete isp;
|
||||
return 0;
|
||||
char*qt2 = strchr(qt1, '"');
|
||||
assert(qt2);
|
||||
|
||||
char*buf = new char[qt2-qt1+1];
|
||||
strncpy(buf, qt1, qt2-qt1);
|
||||
buf[qt2-qt1] = 0;
|
||||
|
||||
delete[]yylloc.text;
|
||||
yylloc.text = buf;
|
||||
|
||||
qt2 += 1;
|
||||
yylloc.first_line = strtoul(qt2,0,0);
|
||||
}
|
||||
|
||||
static void reset_lexor()
|
||||
{
|
||||
yyrestart(vl_input);
|
||||
include_stack = 0;
|
||||
yylloc.first_line = 1;
|
||||
yylloc.text = vl_file.c_str();
|
||||
yylloc.text = strdup(vl_file.c_str());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue