Permalink
Browse files

Support line directives from the preprocessor.

  • Loading branch information...
1 parent 954b42b commit 4939e9fe61afbe1400938228e7754ea24a140e50 steve committed Jul 3, 1999
Showing with 60 additions and 76 deletions.
  1. +32 −5 ivlpp/ivlpp.txt
  2. +28 −71 lexor.lex
View
@@ -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.
+
View
@@ -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()
+static int yywrap()
{
- ppinclude_path = yytext+1;
- ppinclude_path = ppinclude_path.substr(0, ppinclude_path.length()-1);
+ return 1;
}
-static void ppdo_include()
+/*
+ * 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()
{
- FILE*file = fopen(ppinclude_path.c_str(), "r");
- if (file == 0) {
- cerr << ppinclude_path << ": Unable to open include file." << endl;
- return;
- }
+ char*qt1 = strchr(yytext, '"');
+ assert(qt1);
+ qt1 += 1;
- 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;
+ char*qt2 = strchr(qt1, '"');
+ assert(qt2);
- 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;
-}
+ char*buf = new char[qt2-qt1+1];
+ strncpy(buf, qt1, qt2-qt1);
+ buf[qt2-qt1] = 0;
-static int yywrap()
-{
- include_stack_t*isp = include_stack;
- if (isp == 0)
- return 1;
-
- yy_delete_buffer(YY_CURRENT_BUFFER);
- fclose(vl_input);
-
- 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;
+ 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());
}

0 comments on commit 4939e9f

Please sign in to comment.