1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
%{
|
|
|
|
|
/*
|
1999-07-03 23:27:22 +02:00
|
|
|
* Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
|
1998-11-04 00:28:49 +01:00
|
|
|
*
|
|
|
|
|
* This source code is free software; you can redistribute it
|
|
|
|
|
* and/or modify it in source code form under the terms of the GNU
|
|
|
|
|
* General Public License as published by the Free Software
|
|
|
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
|
|
|
*/
|
|
|
|
|
#if !defined(WINNT)
|
1999-09-30 06:51:14 +02:00
|
|
|
#ident "$Id: lexor.lex,v 1.36 1999/09/30 04:51:14 steve Exp $"
|
1998-11-04 00:28:49 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//# define YYSTYPE lexval
|
|
|
|
|
|
|
|
|
|
# include <iostream.h>
|
1999-06-06 22:42:48 +02:00
|
|
|
# include "compiler.h"
|
1998-11-04 00:28:49 +01:00
|
|
|
# include "parse_misc.h"
|
|
|
|
|
# include "parse.h"
|
|
|
|
|
# include <ctype.h>
|
1999-07-10 03:03:18 +02:00
|
|
|
# include <string.h>
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
extern FILE*vl_input;
|
1998-12-09 05:02:47 +01:00
|
|
|
extern string vl_file;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
# define YY_USER_INIT reset_lexor();
|
|
|
|
|
# define yylval VLlval
|
|
|
|
|
extern YYLTYPE yylloc;
|
|
|
|
|
|
|
|
|
|
static void reset_lexor();
|
1999-07-03 23:27:22 +02:00
|
|
|
static void line_directive();
|
|
|
|
|
|
1999-09-29 03:50:35 +02:00
|
|
|
extern int check_identifier(const char*str, int len);
|
1998-11-04 00:28:49 +01:00
|
|
|
static verinum*make_sized_binary(const char*txt);
|
1999-03-16 05:44:45 +01:00
|
|
|
static verinum*make_sized_dec(const char*txt);
|
1999-06-12 05:41:30 +02:00
|
|
|
static verinum*make_unsized_dec(const char*txt);
|
1998-11-04 00:28:49 +01:00
|
|
|
static verinum*make_sized_octal(const char*txt);
|
|
|
|
|
static verinum*make_sized_hex(const char*txt);
|
1999-05-06 06:09:28 +02:00
|
|
|
static verinum*make_unsized_binary(const char*txt);
|
|
|
|
|
static verinum*make_unsized_dec(const char*txt);
|
|
|
|
|
static verinum*make_unsized_octal(const char*txt);
|
|
|
|
|
static verinum*make_unsized_hex(const char*txt);
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-06-22 05:59:37 +02:00
|
|
|
static int comment_enter;
|
1998-11-04 00:28:49 +01:00
|
|
|
%}
|
|
|
|
|
|
|
|
|
|
%x CCOMMENT
|
1999-06-22 05:59:37 +02:00
|
|
|
%x LCOMMENT
|
1998-11-04 00:28:49 +01:00
|
|
|
%x CSTRING
|
1998-11-23 01:20:22 +01:00
|
|
|
%s UDPTABLE
|
1999-06-12 22:35:27 +02:00
|
|
|
%x PPTIMESCALE
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-07-11 19:15:16 +02:00
|
|
|
W [ \t\b\f\r]+
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
%%
|
|
|
|
|
|
1999-07-03 23:27:22 +02:00
|
|
|
^"#line"[ ]+\"[^\"]*\"[ ]+[0-9]+.* { line_directive(); }
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
[ \t\b\f\r] { ; }
|
|
|
|
|
\n { yylloc.first_line += 1; }
|
|
|
|
|
|
1999-06-22 05:59:37 +02:00
|
|
|
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
|
|
|
|
|
<LCOMMENT>. { yymore(); }
|
|
|
|
|
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-06-22 05:59:37 +02:00
|
|
|
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
|
1998-11-04 00:28:49 +01:00
|
|
|
<CCOMMENT>. { yymore(); }
|
|
|
|
|
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
|
1999-06-22 05:59:37 +02:00
|
|
|
<CCOMMENT>"*/" { BEGIN(comment_enter); }
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-05-16 07:08:42 +02:00
|
|
|
"<<" { return K_LS; }
|
|
|
|
|
">>" { return K_RS; }
|
1998-11-04 00:28:49 +01:00
|
|
|
"<=" { return K_LE; }
|
|
|
|
|
">=" { return K_GE; }
|
1999-06-19 05:21:21 +02:00
|
|
|
"=>" { return K_EG; }
|
|
|
|
|
"*>" { return K_SG; }
|
1998-11-07 18:05:05 +01:00
|
|
|
"==" { return K_EQ; }
|
|
|
|
|
"!=" { return K_NE; }
|
|
|
|
|
"===" { return K_CEQ; }
|
|
|
|
|
"!==" { return K_CNE; }
|
1999-03-15 03:43:32 +01:00
|
|
|
"||" { return K_LOR; }
|
|
|
|
|
"&&" { return K_LAND; }
|
1999-06-13 19:30:23 +02:00
|
|
|
"~|" { return K_NOR; }
|
|
|
|
|
"~^" { return K_NXOR; }
|
|
|
|
|
"^~" { return K_NXOR; }
|
|
|
|
|
"~&" { return K_NAND; }
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-05-16 07:08:42 +02:00
|
|
|
[}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
|
1998-11-04 00:28:49 +01:00
|
|
|
|
|
|
|
|
\" { BEGIN(CSTRING); }
|
|
|
|
|
<CSTRING>\\\" { yymore(); }
|
|
|
|
|
<CSTRING>\n { BEGIN(0);
|
1999-07-10 03:03:18 +02:00
|
|
|
yylval.text = strdup(yytext);
|
1998-11-04 00:28:49 +01:00
|
|
|
VLerror(yylloc, "Missing close quote of string.");
|
|
|
|
|
return STRING; }
|
|
|
|
|
<CSTRING>\" { BEGIN(0);
|
1999-07-10 03:03:18 +02:00
|
|
|
yylval.text = strdup(yytext);
|
|
|
|
|
yylval.text[strlen(yytext)-1] = 0;
|
1998-11-04 00:28:49 +01:00
|
|
|
return STRING; }
|
|
|
|
|
<CSTRING>. { yymore(); }
|
|
|
|
|
|
1998-12-18 06:16:25 +01:00
|
|
|
<UDPTABLE>\(\?0\) { return '_'; }
|
|
|
|
|
<UDPTABLE>\(\?1\) { return '+'; }
|
|
|
|
|
<UDPTABLE>\(\?x\) { return '%'; }
|
1998-11-25 03:35:53 +01:00
|
|
|
<UDPTABLE>\(\?\?\) { return '*'; }
|
|
|
|
|
<UDPTABLE>\(01\) { return 'r'; }
|
1998-12-18 06:16:25 +01:00
|
|
|
<UDPTABLE>\(0x\) { return 'P'; }
|
1998-11-25 03:35:53 +01:00
|
|
|
<UDPTABLE>\(10\) { return 'f'; }
|
1998-12-18 06:16:25 +01:00
|
|
|
<UDPTABLE>\(1x\) { return 'N'; }
|
|
|
|
|
<UDPTABLE>\(x0\) { return 'F'; }
|
|
|
|
|
<UDPTABLE>\(x1\) { return 'R'; }
|
1998-11-25 03:35:53 +01:00
|
|
|
<UDPTABLE>[bB] { return 'b'; }
|
|
|
|
|
<UDPTABLE>[fF] { return 'f'; }
|
|
|
|
|
<UDPTABLE>[rR] { return 'r'; }
|
|
|
|
|
<UDPTABLE>[xX] { return 'x'; }
|
|
|
|
|
<UDPTABLE>[pPnN01\?\*\-] { return yytext[0]; }
|
1998-11-23 01:20:22 +01:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
[a-zA-Z_][a-zA-Z0-9$_]* {
|
1999-09-29 03:50:35 +02:00
|
|
|
int rc = check_identifier(yytext, yyleng);
|
1998-11-04 00:28:49 +01:00
|
|
|
if (rc == IDENTIFIER)
|
1999-07-10 03:03:18 +02:00
|
|
|
yylval.text = strdup(yytext);
|
1998-11-04 00:28:49 +01:00
|
|
|
else
|
|
|
|
|
yylval.text = 0;
|
|
|
|
|
|
|
|
|
|
return rc; }
|
|
|
|
|
|
1999-06-16 05:13:29 +02:00
|
|
|
[a-zA-Z_][a-zA-Z0-9$_]*(\.[a-zA-Z_][a-zA-Z0-9$_]*)+ {
|
1999-07-10 03:03:18 +02:00
|
|
|
yylval.text = strdup(yytext);
|
1999-06-16 05:13:29 +02:00
|
|
|
return HIDENTIFIER; }
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
\\[^ \t\b\f\r]+ {
|
1999-07-10 03:03:18 +02:00
|
|
|
yylval.text = strdup(yytext);
|
1998-11-04 00:28:49 +01:00
|
|
|
return IDENTIFIER; }
|
|
|
|
|
|
|
|
|
|
\$([a-zA-Z0-9$_]+) {
|
1998-11-23 01:20:22 +01:00
|
|
|
if (strcmp(yytext,"$attribute") == 0)
|
|
|
|
|
return KK_attribute;
|
1999-07-10 03:03:18 +02:00
|
|
|
yylval.text = strdup(yytext);
|
1998-11-04 00:28:49 +01:00
|
|
|
return SYSTEM_IDENTIFIER; }
|
|
|
|
|
|
1999-09-30 06:51:14 +02:00
|
|
|
\.{W}?[a-zA-Z_][a-zA-Z0-9$_]* {
|
|
|
|
|
char*cp = yytext+1;
|
|
|
|
|
while (! (isalpha(*cp) || (*cp == '_')))
|
|
|
|
|
cp += 1;
|
|
|
|
|
yylval.text = strdup(cp);
|
1999-05-08 22:19:20 +02:00
|
|
|
return PORTNAME; }
|
|
|
|
|
|
1999-06-14 05:15:14 +02:00
|
|
|
[0-9][0-9_]*[ \t]*\'d[ \t]*[0-9][0-9_]* {
|
|
|
|
|
yylval.number = make_sized_dec(yytext);
|
|
|
|
|
return NUMBER; }
|
1999-07-08 04:06:39 +02:00
|
|
|
[0-9][0-9_]*[ \t]*\'[bB][ \t]*[0-1xzXZ_\?]+ {
|
1999-06-14 05:15:14 +02:00
|
|
|
yylval.number = make_sized_binary(yytext);
|
|
|
|
|
return NUMBER; }
|
1999-07-08 04:06:39 +02:00
|
|
|
[0-9][0-9_]*[ \t]*\'[oO][ \t]*[0-7xzXZ_\?]+ {
|
1999-06-14 05:15:14 +02:00
|
|
|
yylval.number = make_sized_octal(yytext);
|
|
|
|
|
return NUMBER; }
|
1999-07-08 04:06:39 +02:00
|
|
|
[0-9][0-9_]*[ \t]*\'[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ {
|
1999-06-14 05:15:14 +02:00
|
|
|
yylval.number = make_sized_hex(yytext);
|
|
|
|
|
return NUMBER; }
|
|
|
|
|
|
|
|
|
|
\'d[ \t]*[0-9][0-9_]* { yylval.number = make_unsized_dec(yytext);
|
|
|
|
|
return NUMBER; }
|
1999-07-08 04:06:39 +02:00
|
|
|
\'[bB][ \t]*[0-1xzXZ_\?]+ { yylval.number = make_unsized_binary(yytext);
|
1999-06-14 05:15:14 +02:00
|
|
|
return NUMBER; }
|
1999-07-08 04:06:39 +02:00
|
|
|
\'[oO][ \t]*[0-7xzXZ_\?]+ { yylval.number = make_unsized_octal(yytext);
|
1999-05-06 06:09:28 +02:00
|
|
|
return NUMBER; }
|
1999-07-08 04:06:39 +02:00
|
|
|
\'[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext);
|
1999-06-14 05:15:14 +02:00
|
|
|
return NUMBER; }
|
1999-05-06 06:09:28 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
[0-9][0-9_]* {
|
|
|
|
|
/* Handle the special case of the unsized decimal number. */
|
|
|
|
|
unsigned long value = 0;
|
|
|
|
|
for (const char*cp = yytext ; *cp ; cp += 1) {
|
|
|
|
|
if (*cp != '_')
|
|
|
|
|
value = 10 * value + (*cp - '0');
|
|
|
|
|
}
|
|
|
|
|
|
1999-06-07 01:08:00 +02:00
|
|
|
assert(INTEGER_WIDTH <= (8*sizeof(value)));
|
|
|
|
|
unsigned nbits = INTEGER_WIDTH;
|
1998-11-04 00:28:49 +01:00
|
|
|
verinum::V*bits = new verinum::V[8 * sizeof value];
|
|
|
|
|
|
|
|
|
|
for (unsigned idx = 0 ; idx < nbits ; idx += 1, value >>= 1) {
|
|
|
|
|
bits[idx] = (value&1) ? verinum::V1 : verinum::V0;
|
|
|
|
|
}
|
|
|
|
|
|
1999-05-13 06:02:09 +02:00
|
|
|
yylval.number = new verinum(bits, nbits, false);
|
1998-11-04 00:28:49 +01:00
|
|
|
delete[]bits;
|
|
|
|
|
return NUMBER; }
|
|
|
|
|
|
1999-06-15 04:50:02 +02:00
|
|
|
[0-9][0-9_]*\.[0-9][0-9_]*([Ee][+-]?[0-9][0-9_]*)? {
|
|
|
|
|
yylval.realtime = new verireal(yytext);
|
|
|
|
|
return REALTIME; }
|
|
|
|
|
|
|
|
|
|
[0-9][0-9_]*[Ee][+-]?[0-9][0-9_]* {
|
|
|
|
|
yylval.realtime = new verireal(yytext);
|
|
|
|
|
return REALTIME; }
|
|
|
|
|
|
1999-07-11 19:15:16 +02:00
|
|
|
|
|
|
|
|
/* Notice and handle the timescale directive. */
|
1999-06-15 04:50:02 +02:00
|
|
|
|
1999-06-12 22:35:27 +02:00
|
|
|
`timescale { BEGIN(PPTIMESCALE); }
|
|
|
|
|
<PPTIMESCALE>. { ; }
|
|
|
|
|
<PPTIMESCALE>\n {
|
|
|
|
|
cerr << yylloc.text << ":" << yylloc.first_line
|
|
|
|
|
<< ": Sorry, `timescale not supported." << endl;
|
|
|
|
|
yylloc.first_line += 1;
|
|
|
|
|
BEGIN(0); }
|
|
|
|
|
|
1998-12-09 05:02:47 +01:00
|
|
|
|
1999-07-11 19:15:16 +02:00
|
|
|
/* These are directives that I do not yet support. I think that IVL
|
|
|
|
|
should handle these, not an external preprocessor. */
|
|
|
|
|
|
|
|
|
|
^`celldefine{W}?.* { }
|
|
|
|
|
^`default_nettype{W}?.* { }
|
|
|
|
|
^`delay_mode_distributed{W}?.* { }
|
|
|
|
|
^`delay_mode_unit{W}?.* { }
|
|
|
|
|
^`delay_mode_path{W}?.* { }
|
|
|
|
|
^`disable_portfaults{W}?.* { }
|
|
|
|
|
^`enable_portfaults{W}?.* { }
|
|
|
|
|
^`endcelldefine{W}?.* { }
|
|
|
|
|
^`endprotect{W}?.* { }
|
|
|
|
|
^`nosuppress_faults{W}?.* { }
|
|
|
|
|
^`nounconnected_drive{W}?* { }
|
|
|
|
|
^`protect{W}?.* { }
|
|
|
|
|
^`resetall{W}?.* { }
|
|
|
|
|
^`suppress_faults{W}?.* { }
|
|
|
|
|
^`unconnected_drive{W}?* { }
|
|
|
|
|
^`uselib{W}?.* { }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* These are directives that are not supported by me and should have
|
|
|
|
|
been handled by an external preprocessor such as ivlpp. */
|
|
|
|
|
|
|
|
|
|
^`define{W}?.* {
|
|
|
|
|
cerr << yylloc.text << ":" << yylloc.first_line <<
|
|
|
|
|
": `define not supported. Use an external preprocessor."
|
|
|
|
|
<< endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
^{W}?`else{W}?.* {
|
|
|
|
|
cerr << yylloc.text << ":" << yylloc.first_line <<
|
|
|
|
|
": `else not supported. Use an external preprocessor."
|
|
|
|
|
<< endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
^{W}?`endif{W}?.* {
|
|
|
|
|
cerr << yylloc.text << ":" << yylloc.first_line <<
|
|
|
|
|
": `endif not supported. Use an external preprocessor."
|
|
|
|
|
<< endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
^{W}?`ifdef{W}?.* {
|
|
|
|
|
cerr << yylloc.text << ":" << yylloc.first_line <<
|
|
|
|
|
": `ifdef not supported. Use an external preprocessor."
|
|
|
|
|
<< endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
^`include{W}?.* {
|
|
|
|
|
cerr << yylloc.text << ":" << yylloc.first_line <<
|
|
|
|
|
": `include not supported. Use an external preprocessor."
|
|
|
|
|
<< endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
^`undef{W}?.* {
|
|
|
|
|
cerr << yylloc.text << ":" << yylloc.first_line <<
|
|
|
|
|
": `undef not supported. Use an external preprocessor."
|
|
|
|
|
<< endl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Final catchall. something got lost or mishandled. */
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
. { cerr << yylloc.first_line << ": unmatched character (";
|
|
|
|
|
if (isgraph(yytext[0]))
|
|
|
|
|
cerr << yytext[0];
|
|
|
|
|
else
|
|
|
|
|
cerr << (unsigned)yytext[0];
|
|
|
|
|
|
|
|
|
|
cerr << ")" << endl; }
|
|
|
|
|
|
|
|
|
|
%%
|
|
|
|
|
|
1998-11-23 01:20:22 +01:00
|
|
|
/*
|
|
|
|
|
* The UDP state table needs some slightly different treatment by the
|
|
|
|
|
* lexor. The level characters are normally accepted as other things,
|
|
|
|
|
* so the parser needs to switch my mode when it believes in needs to.
|
|
|
|
|
*/
|
|
|
|
|
void lex_start_table()
|
|
|
|
|
{
|
|
|
|
|
BEGIN(UDPTABLE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void lex_end_table()
|
|
|
|
|
{
|
|
|
|
|
BEGIN(INITIAL);
|
|
|
|
|
}
|
|
|
|
|
|
1999-05-13 06:02:09 +02:00
|
|
|
static verinum*make_binary_with_size(unsigned size, bool fixed, const char*ptr)
|
1998-11-04 00:28:49 +01:00
|
|
|
{
|
|
|
|
|
assert(tolower(*ptr) == 'b');
|
|
|
|
|
verinum::V*bits = new verinum::V[size];
|
|
|
|
|
|
1999-06-14 05:15:14 +02:00
|
|
|
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
|
|
|
|
ptr += 1;
|
|
|
|
|
|
1998-11-25 03:35:53 +01:00
|
|
|
unsigned idx = 0;
|
1999-05-06 06:09:28 +02:00
|
|
|
const char*eptr = ptr + strlen(ptr) - 1;
|
1998-11-04 00:28:49 +01:00
|
|
|
while ((eptr > ptr) && (idx < size)) {
|
|
|
|
|
|
|
|
|
|
if (*eptr == '_') {
|
|
|
|
|
eptr -= 1;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (*eptr) {
|
|
|
|
|
case '0':
|
|
|
|
|
bits[idx++] = verinum::V0;
|
|
|
|
|
break;
|
|
|
|
|
case '1':
|
|
|
|
|
bits[idx++] = verinum::V1;
|
|
|
|
|
break;
|
1999-07-08 04:06:39 +02:00
|
|
|
case 'z': case 'Z': case '?':
|
1998-11-04 00:28:49 +01:00
|
|
|
bits[idx++] = verinum::Vz;
|
|
|
|
|
break;
|
1999-07-07 02:24:42 +02:00
|
|
|
case 'x': case 'X':
|
1998-11-04 00:28:49 +01:00
|
|
|
bits[idx++] = verinum::Vx;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eptr -= 1;
|
|
|
|
|
}
|
|
|
|
|
// Zero-extend binary number, except that z or x is extended
|
|
|
|
|
// if it is the highest supplied digit.
|
1998-11-25 03:35:53 +01:00
|
|
|
while (idx < size) {
|
1998-11-04 00:28:49 +01:00
|
|
|
switch (ptr[1]) {
|
|
|
|
|
case '0':
|
|
|
|
|
case '1':
|
|
|
|
|
bits[idx++] = verinum::V0;
|
|
|
|
|
break;
|
1999-07-08 04:06:39 +02:00
|
|
|
case 'z': case 'Z': case '?':
|
1998-11-04 00:28:49 +01:00
|
|
|
bits[idx++] = verinum::Vz;
|
|
|
|
|
break;
|
1999-07-07 02:24:42 +02:00
|
|
|
case 'x': case 'X':
|
1998-11-04 00:28:49 +01:00
|
|
|
bits[idx++] = verinum::Vx;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-05-13 06:02:09 +02:00
|
|
|
return new verinum(bits, size, fixed);
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
|
1999-05-06 06:09:28 +02:00
|
|
|
static verinum*make_sized_binary(const char*txt)
|
|
|
|
|
{
|
|
|
|
|
char*ptr;
|
|
|
|
|
unsigned size = strtoul(txt,&ptr,10);
|
1999-06-14 05:15:14 +02:00
|
|
|
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
|
|
|
|
ptr += 1;
|
1999-05-06 06:09:28 +02:00
|
|
|
assert(*ptr == '\'');
|
|
|
|
|
ptr += 1;
|
|
|
|
|
assert(tolower(*ptr) == 'b');
|
|
|
|
|
|
1999-05-13 06:02:09 +02:00
|
|
|
return make_binary_with_size(size, true, ptr);
|
1999-05-06 06:09:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static verinum*make_unsized_binary(const char*txt)
|
|
|
|
|
{
|
1999-06-14 05:15:14 +02:00
|
|
|
const char*ptr = txt;
|
|
|
|
|
assert(*ptr == '\'');
|
|
|
|
|
ptr += 1;
|
|
|
|
|
assert(tolower(*ptr) == 'b');
|
1999-07-07 02:24:42 +02:00
|
|
|
while (*ptr && ((*ptr == 'b') || (*ptr == ' ') || (*ptr == '\t')))
|
1999-06-14 05:15:14 +02:00
|
|
|
ptr += 1;
|
|
|
|
|
|
|
|
|
|
unsigned size = 0;
|
|
|
|
|
for (const char*idx = ptr ; *idx ; idx += 1)
|
|
|
|
|
if (*idx != '_') size += 1;
|
|
|
|
|
|
|
|
|
|
verinum::V*bits = new verinum::V[size];
|
|
|
|
|
|
|
|
|
|
unsigned idx = size;
|
|
|
|
|
while (*ptr) {
|
|
|
|
|
switch (ptr[0]) {
|
|
|
|
|
case '0':
|
|
|
|
|
bits[--idx] = verinum::V0;
|
|
|
|
|
break;
|
|
|
|
|
case '1':
|
|
|
|
|
bits[--idx] = verinum::V1;
|
|
|
|
|
break;
|
1999-07-08 04:06:39 +02:00
|
|
|
case 'z': case 'Z': case '?':
|
1999-06-14 05:15:14 +02:00
|
|
|
bits[--idx] = verinum::Vz;
|
|
|
|
|
break;
|
|
|
|
|
case 'x': case 'X':
|
|
|
|
|
bits[--idx] = verinum::Vx;
|
|
|
|
|
break;
|
|
|
|
|
case '_':
|
|
|
|
|
break;
|
|
|
|
|
default:
|
1999-07-07 02:24:42 +02:00
|
|
|
fprintf(stderr, "%c\n", ptr[0]);
|
1999-06-14 05:15:14 +02:00
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
ptr += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new verinum(bits, size);
|
1999-05-06 06:09:28 +02:00
|
|
|
}
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
static verinum*make_sized_octal(const char*txt)
|
|
|
|
|
{
|
|
|
|
|
char*ptr;
|
|
|
|
|
unsigned size = strtoul(txt,&ptr,10);
|
1999-06-14 05:15:14 +02:00
|
|
|
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
|
|
|
|
ptr += 1;
|
1998-11-04 00:28:49 +01:00
|
|
|
assert(*ptr == '\'');
|
|
|
|
|
ptr += 1;
|
|
|
|
|
assert(tolower(*ptr) == 'o');
|
|
|
|
|
|
1999-09-13 05:08:52 +02:00
|
|
|
/* We know from the size number how bit to make the verinom
|
|
|
|
|
array, so make it now. */
|
1998-11-04 00:28:49 +01:00
|
|
|
verinum::V*bits = new verinum::V[size];
|
|
|
|
|
|
1999-09-13 05:08:52 +02:00
|
|
|
/* skip white space between size and the base token. */
|
1999-06-14 05:15:14 +02:00
|
|
|
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
|
|
|
|
ptr += 1;
|
|
|
|
|
|
1999-09-13 05:08:52 +02:00
|
|
|
/* Find the end of the digits. ptr already points to the start. */
|
1998-11-04 00:28:49 +01:00
|
|
|
char*eptr = ptr + strlen(ptr);
|
|
|
|
|
|
1999-09-13 05:08:52 +02:00
|
|
|
/* From the last digit and forward, build up the number, least
|
|
|
|
|
significant bit first. This loop will not get the last few
|
|
|
|
|
bits if the size is not a multiple of 3. */
|
|
|
|
|
unsigned idx = 0;
|
|
|
|
|
while ((eptr > ptr) && ((idx/3) < (size/3))) switch (*--eptr) {
|
|
|
|
|
|
1999-07-07 02:24:42 +02:00
|
|
|
case 'x': case 'X':
|
1998-11-04 00:28:49 +01:00
|
|
|
bits[idx++] = verinum::Vx;
|
|
|
|
|
bits[idx++] = verinum::Vx;
|
|
|
|
|
bits[idx++] = verinum::Vx;
|
|
|
|
|
break;
|
1999-09-13 05:08:52 +02:00
|
|
|
|
1999-07-08 04:06:39 +02:00
|
|
|
case 'z': case 'Z': case '?':
|
1998-11-04 00:28:49 +01:00
|
|
|
bits[idx++] = verinum::Vz;
|
|
|
|
|
bits[idx++] = verinum::Vz;
|
|
|
|
|
bits[idx++] = verinum::Vz;
|
|
|
|
|
break;
|
1999-09-13 05:08:52 +02:00
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
default: {
|
|
|
|
|
unsigned val = *eptr - '0';
|
|
|
|
|
bits[idx++] = (val&1)? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[idx++] = (val&2)? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[idx++] = (val&4)? verinum::V1 : verinum::V0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-09-13 05:08:52 +02:00
|
|
|
if ((eptr > ptr) && (idx < size)) switch (*--eptr) {
|
|
|
|
|
|
1999-07-07 02:24:42 +02:00
|
|
|
case 'x': case 'X':
|
1999-09-13 05:08:52 +02:00
|
|
|
for ( ; idx < size ; idx += 1)
|
|
|
|
|
bits[idx] = verinum::Vx;
|
1998-11-04 00:28:49 +01:00
|
|
|
break;
|
1999-09-13 05:08:52 +02:00
|
|
|
|
1999-07-08 04:06:39 +02:00
|
|
|
case 'z': case 'Z': case '?':
|
1999-09-13 05:08:52 +02:00
|
|
|
for ( ; idx < size ; idx += 1)
|
|
|
|
|
bits[idx] = verinum::Vz;
|
1998-11-04 00:28:49 +01:00
|
|
|
break;
|
1999-09-13 05:08:52 +02:00
|
|
|
|
|
|
|
|
default: {
|
|
|
|
|
unsigned val = *eptr - '0';
|
|
|
|
|
for ( ; idx < size ; idx += 1) {
|
|
|
|
|
bits[idx] = (val&1)? verinum::V1 : verinum::V0;
|
|
|
|
|
val >>= 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
// zero extend octal numbers
|
|
|
|
|
while (idx < size) switch (ptr[1]) {
|
|
|
|
|
case 'x': case 'X':
|
|
|
|
|
bits[idx++] = verinum::Vx;
|
|
|
|
|
break;
|
|
|
|
|
case 'z': case 'Z': case '?':
|
|
|
|
|
bits[idx++] = verinum::Vz;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
bits[idx++] = verinum::V0;
|
|
|
|
|
}
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
|
1999-05-13 06:02:09 +02:00
|
|
|
return new verinum(bits, size, true);
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
|
1999-05-06 06:09:28 +02:00
|
|
|
static verinum*make_unsized_octal(const char*txt)
|
|
|
|
|
{
|
1999-06-13 19:30:23 +02:00
|
|
|
const char*ptr = txt;
|
|
|
|
|
assert(*ptr == '\'');
|
|
|
|
|
ptr += 1;
|
|
|
|
|
assert(tolower(*ptr) == 'o');
|
|
|
|
|
ptr += 1;
|
|
|
|
|
|
1999-06-14 05:15:14 +02:00
|
|
|
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
|
|
|
|
ptr += 1;
|
|
|
|
|
|
|
|
|
|
unsigned size = 0;
|
|
|
|
|
for (const char*idx = ptr ; *idx ; idx += 1)
|
|
|
|
|
if (*idx != '_') size += 3;
|
|
|
|
|
|
1999-06-13 19:30:23 +02:00
|
|
|
verinum::V*bits = new verinum::V[size];
|
|
|
|
|
|
|
|
|
|
unsigned idx = size;
|
|
|
|
|
while (*ptr) {
|
|
|
|
|
unsigned val;
|
|
|
|
|
switch (ptr[0]) {
|
|
|
|
|
case '0': case '1': case '2': case '3':
|
|
|
|
|
case '4': case '5': case '6': case '7':
|
|
|
|
|
val = *ptr - '0';
|
|
|
|
|
bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
|
|
|
|
|
break;
|
1999-07-07 02:24:42 +02:00
|
|
|
case 'x': case 'X':
|
1999-06-13 19:30:23 +02:00
|
|
|
bits[--idx] = verinum::Vx;
|
|
|
|
|
bits[--idx] = verinum::Vx;
|
|
|
|
|
bits[--idx] = verinum::Vx;
|
|
|
|
|
break;
|
1999-07-08 04:06:39 +02:00
|
|
|
case 'z': case 'Z': case '?':
|
1999-06-13 19:30:23 +02:00
|
|
|
bits[--idx] = verinum::Vz;
|
|
|
|
|
bits[--idx] = verinum::Vz;
|
|
|
|
|
bits[--idx] = verinum::Vz;
|
|
|
|
|
break;
|
1999-06-14 05:15:14 +02:00
|
|
|
case '_':
|
|
|
|
|
break;
|
1999-06-13 19:30:23 +02:00
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
ptr += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new verinum(bits, size);
|
1999-05-06 06:09:28 +02:00
|
|
|
}
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
static verinum*make_sized_hex(const char*txt)
|
|
|
|
|
{
|
|
|
|
|
char*ptr;
|
|
|
|
|
unsigned size = strtoul(txt,&ptr,10);
|
1999-06-14 05:15:14 +02:00
|
|
|
|
|
|
|
|
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
|
|
|
|
ptr += 1;
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
assert(*ptr == '\'');
|
|
|
|
|
ptr += 1;
|
|
|
|
|
assert(tolower(*ptr) == 'h');
|
|
|
|
|
|
1999-06-14 05:15:14 +02:00
|
|
|
ptr += 1;
|
|
|
|
|
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
|
|
|
|
ptr += 1;
|
|
|
|
|
|
1999-07-17 20:25:38 +02:00
|
|
|
verinum::V*bits = new verinum::V[(size+3)&~3];
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1998-11-25 03:35:53 +01:00
|
|
|
unsigned idx = 0;
|
1999-02-15 06:52:08 +01:00
|
|
|
char*eptr = ptr + strlen(ptr) - 1;
|
1998-11-04 00:28:49 +01:00
|
|
|
|
1999-07-17 20:25:38 +02:00
|
|
|
while ((eptr >= ptr) && (idx < size)) {
|
1998-11-04 00:28:49 +01:00
|
|
|
switch (*eptr) {
|
1999-07-07 02:24:42 +02:00
|
|
|
case 'x': case 'X':
|
1998-11-04 00:28:49 +01:00
|
|
|
bits[idx++] = verinum::Vx;
|
|
|
|
|
bits[idx++] = verinum::Vx;
|
|
|
|
|
bits[idx++] = verinum::Vx;
|
|
|
|
|
bits[idx++] = verinum::Vx;
|
|
|
|
|
break;
|
1999-07-08 04:06:39 +02:00
|
|
|
case 'z': case 'Z': case '?':
|
1998-11-04 00:28:49 +01:00
|
|
|
bits[idx++] = verinum::Vz;
|
|
|
|
|
bits[idx++] = verinum::Vz;
|
|
|
|
|
bits[idx++] = verinum::Vz;
|
|
|
|
|
bits[idx++] = verinum::Vz;
|
|
|
|
|
break;
|
|
|
|
|
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
|
|
|
|
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
|
|
|
|
{
|
|
|
|
|
unsigned val = tolower(*eptr) - 'a' + 10;
|
|
|
|
|
bits[idx++] = (val&1)? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[idx++] = (val&2)? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[idx++] = (val&4)? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[idx++] = (val&8)? verinum::V1 : verinum::V0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
1999-02-15 06:52:08 +01:00
|
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
|
|
|
case '5': case '6': case '7': case '8': case '9':
|
1998-11-04 00:28:49 +01:00
|
|
|
{
|
|
|
|
|
unsigned val = *eptr - '0';
|
|
|
|
|
bits[idx++] = (val&1)? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[idx++] = (val&2)? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[idx++] = (val&4)? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[idx++] = (val&8)? verinum::V1 : verinum::V0;
|
1999-02-15 06:52:08 +01:00
|
|
|
break;
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
1999-06-14 05:15:14 +02:00
|
|
|
case '_':
|
|
|
|
|
break;
|
1999-02-15 06:52:08 +01:00
|
|
|
default:
|
|
|
|
|
assert(0);
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eptr -= 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// zero extend octal numbers
|
1998-11-25 03:35:53 +01:00
|
|
|
while (idx < size) switch (ptr[1]) {
|
1999-07-07 02:24:42 +02:00
|
|
|
case 'x': case 'X':
|
1998-11-04 00:28:49 +01:00
|
|
|
bits[idx++] = verinum::Vx;
|
|
|
|
|
break;
|
1999-07-08 04:06:39 +02:00
|
|
|
case 'z': case 'Z': case '?':
|
1998-11-04 00:28:49 +01:00
|
|
|
bits[idx++] = verinum::Vz;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
bits[idx++] = verinum::V0;
|
|
|
|
|
}
|
|
|
|
|
|
1999-05-13 06:02:09 +02:00
|
|
|
return new verinum(bits, size, true);
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|
|
|
|
|
|
1999-05-06 06:09:28 +02:00
|
|
|
static verinum*make_unsized_hex(const char*txt)
|
|
|
|
|
{
|
1999-06-13 19:30:23 +02:00
|
|
|
const char*ptr = txt;
|
|
|
|
|
assert(*ptr == '\'');
|
|
|
|
|
ptr += 1;
|
|
|
|
|
assert(tolower(*ptr) == 'h');
|
1999-06-14 05:15:14 +02:00
|
|
|
|
1999-06-13 19:30:23 +02:00
|
|
|
ptr += 1;
|
1999-06-14 05:15:14 +02:00
|
|
|
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
|
|
|
|
ptr += 1;
|
|
|
|
|
|
|
|
|
|
unsigned size = 0;
|
|
|
|
|
for (const char*idx = ptr ; *idx ; idx += 1)
|
|
|
|
|
if (*idx != '_') size += 4;
|
1999-06-13 19:30:23 +02:00
|
|
|
|
|
|
|
|
verinum::V*bits = new verinum::V[size];
|
|
|
|
|
|
|
|
|
|
unsigned idx = size;
|
|
|
|
|
while (*ptr) {
|
|
|
|
|
unsigned val;
|
|
|
|
|
switch (ptr[0]) {
|
|
|
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
|
|
|
case '5': case '6': case '7': case '8': case '9':
|
|
|
|
|
val = *ptr - '0';
|
|
|
|
|
bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
|
|
|
|
|
break;
|
|
|
|
|
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
|
|
|
|
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
|
|
|
|
val = tolower(*ptr) - 'a' + 10;
|
|
|
|
|
bits[--idx] = (val&8) ? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[--idx] = (val&4) ? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[--idx] = (val&2) ? verinum::V1 : verinum::V0;
|
|
|
|
|
bits[--idx] = (val&1) ? verinum::V1 : verinum::V0;
|
|
|
|
|
break;
|
1999-07-07 02:24:42 +02:00
|
|
|
case 'x': case 'X':
|
1999-06-13 19:30:23 +02:00
|
|
|
bits[--idx] = verinum::Vx;
|
|
|
|
|
bits[--idx] = verinum::Vx;
|
|
|
|
|
bits[--idx] = verinum::Vx;
|
|
|
|
|
bits[--idx] = verinum::Vx;
|
|
|
|
|
break;
|
1999-07-08 04:06:39 +02:00
|
|
|
case 'z': case 'Z': case '?':
|
1999-06-13 19:30:23 +02:00
|
|
|
bits[--idx] = verinum::Vz;
|
|
|
|
|
bits[--idx] = verinum::Vz;
|
|
|
|
|
bits[--idx] = verinum::Vz;
|
|
|
|
|
bits[--idx] = verinum::Vz;
|
|
|
|
|
break;
|
1999-06-14 05:15:14 +02:00
|
|
|
case '_':
|
|
|
|
|
break;
|
1999-06-13 19:30:23 +02:00
|
|
|
default:
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
ptr += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new verinum(bits, size);
|
1999-05-06 06:09:28 +02:00
|
|
|
}
|
|
|
|
|
|
1999-03-16 05:44:45 +01:00
|
|
|
/*
|
1999-06-12 05:41:30 +02:00
|
|
|
* Making a decimal number is much easier then the other base numbers
|
1999-03-16 05:44:45 +01:00
|
|
|
* because there are no z or x values to worry about.
|
|
|
|
|
*/
|
1999-06-12 05:41:30 +02:00
|
|
|
static verinum*make_dec_with_size(unsigned size, bool fixed, const char*ptr)
|
1999-03-16 05:44:45 +01:00
|
|
|
{
|
|
|
|
|
assert(tolower(*ptr) == 'd');
|
|
|
|
|
|
1999-06-14 05:15:14 +02:00
|
|
|
ptr += 1;
|
|
|
|
|
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
|
|
|
|
ptr += 1;
|
|
|
|
|
|
1999-03-16 05:44:45 +01:00
|
|
|
unsigned long value = 0;
|
1999-06-14 05:15:14 +02:00
|
|
|
for ( ; *ptr ; ptr += 1)
|
1999-03-16 05:44:45 +01:00
|
|
|
if (isdigit(*ptr)) {
|
|
|
|
|
value *= 10;
|
|
|
|
|
value += *ptr - '0';
|
|
|
|
|
} else {
|
|
|
|
|
assert(*ptr == '_');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
verinum::V*bits = new verinum::V[size];
|
|
|
|
|
|
|
|
|
|
for (unsigned idx = 0 ; idx < size ; idx += 1) {
|
|
|
|
|
bits[idx] = (value&1)? verinum::V1 : verinum::V0;
|
|
|
|
|
value /= 2;
|
|
|
|
|
}
|
|
|
|
|
|
1999-06-12 05:41:30 +02:00
|
|
|
return new verinum(bits, size, fixed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static verinum*make_sized_dec(const char*txt)
|
|
|
|
|
{
|
|
|
|
|
char*ptr;
|
|
|
|
|
unsigned size = strtoul(txt,&ptr,10);
|
1999-06-14 05:15:14 +02:00
|
|
|
|
|
|
|
|
while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
|
|
|
|
|
ptr += 1;
|
|
|
|
|
|
1999-06-12 05:41:30 +02:00
|
|
|
assert(*ptr == '\'');
|
|
|
|
|
ptr += 1;
|
|
|
|
|
assert(tolower(*ptr) == 'd');
|
|
|
|
|
|
|
|
|
|
return make_dec_with_size(size, true, ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static verinum*make_unsized_dec(const char*txt)
|
|
|
|
|
{
|
|
|
|
|
return make_dec_with_size(INTEGER_WIDTH, false, txt+1);
|
1999-03-16 05:44:45 +01:00
|
|
|
}
|
|
|
|
|
|
1998-12-09 05:02:47 +01:00
|
|
|
|
1999-07-03 23:27:22 +02:00
|
|
|
static int yywrap()
|
1998-12-09 05:02:47 +01:00
|
|
|
{
|
1999-07-03 23:27:22 +02:00
|
|
|
return 1;
|
1998-12-09 05:02:47 +01:00
|
|
|
}
|
|
|
|
|
|
1999-07-03 23:27:22 +02:00
|
|
|
/*
|
|
|
|
|
* 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()
|
1998-12-09 05:02:47 +01:00
|
|
|
{
|
1999-07-03 23:27:22 +02:00
|
|
|
char*qt1 = strchr(yytext, '"');
|
|
|
|
|
assert(qt1);
|
|
|
|
|
qt1 += 1;
|
1998-12-09 05:02:47 +01:00
|
|
|
|
1999-07-03 23:27:22 +02:00
|
|
|
char*qt2 = strchr(qt1, '"');
|
|
|
|
|
assert(qt2);
|
1998-12-09 05:02:47 +01:00
|
|
|
|
1999-07-03 23:27:22 +02:00
|
|
|
char*buf = new char[qt2-qt1+1];
|
|
|
|
|
strncpy(buf, qt1, qt2-qt1);
|
|
|
|
|
buf[qt2-qt1] = 0;
|
1998-12-09 05:02:47 +01:00
|
|
|
|
1999-07-03 23:27:22 +02:00
|
|
|
delete[]yylloc.text;
|
|
|
|
|
yylloc.text = buf;
|
|
|
|
|
|
|
|
|
|
qt2 += 1;
|
|
|
|
|
yylloc.first_line = strtoul(qt2,0,0);
|
1998-12-09 05:02:47 +01:00
|
|
|
}
|
|
|
|
|
|
1998-11-04 00:28:49 +01:00
|
|
|
static void reset_lexor()
|
|
|
|
|
{
|
|
|
|
|
yyrestart(vl_input);
|
|
|
|
|
yylloc.first_line = 1;
|
1999-07-03 23:27:22 +02:00
|
|
|
yylloc.text = strdup(vl_file.c_str());
|
1998-11-04 00:28:49 +01:00
|
|
|
}
|