163 lines
3.9 KiB
Plaintext
163 lines
3.9 KiB
Plaintext
%option prefix="tblmod"
|
|
%option never-interactive
|
|
%option noinput
|
|
%option nounput
|
|
%option noyywrap
|
|
|
|
%{
|
|
/*
|
|
* Copyright (C) 2011-2017 Cary R. (cygcary@yahoo.com)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it 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.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "table_mod.h"
|
|
#include "table_mod_parse.h"
|
|
#include "ivl_alloc.h"
|
|
|
|
static double get_scaled_real(const char *text);
|
|
static double get_real(const char *text);
|
|
|
|
#define yylval tblmodlval
|
|
%}
|
|
|
|
SPACE [ \t]
|
|
EOL [\r\n]+
|
|
SCALE [afpnumkKMGT]
|
|
|
|
%%
|
|
|
|
/* Skip comment lines. */
|
|
"#".*{EOL} {
|
|
tblmodlloc.first_line += 1;
|
|
}
|
|
|
|
/* Skip white space. */
|
|
{SPACE} { ; }
|
|
|
|
{EOL} {
|
|
tblmodlloc.first_line += 1;
|
|
return END_LINE;
|
|
}
|
|
|
|
/* Recognize a real value with a Verilog-AMS scale. */
|
|
[+-]?[0-9][0-9_]*(\.[0-9][0-9_]*)?{SCALE} {
|
|
yylval.real = get_scaled_real(yytext);
|
|
return REAL;
|
|
}
|
|
|
|
/* Recognize and other numeric value. */
|
|
[+-]?[0-9][0-9_]*(\.[0-9][0-9_]*)?([eE][+-]?[0-9][0-9_]*)? {
|
|
yylval.real = get_real(yytext);
|
|
return REAL;
|
|
}
|
|
|
|
%%
|
|
|
|
/*
|
|
* Convert a Verilog-AMS scaled real number to a real value.
|
|
*/
|
|
double get_scaled_real(const char *text)
|
|
{
|
|
double result;
|
|
size_t len = strlen(text);
|
|
char *buf = malloc(len + 5);
|
|
const char *scale;
|
|
|
|
/* Copy the number to the buffer. */
|
|
strcpy(buf, text);
|
|
|
|
/* Convert the scale character to exponential form. */
|
|
switch (text[len-1]) {
|
|
case 'a': scale = "e-18"; break; /* atto */
|
|
case 'f': scale = "e-15"; break; /* femto */
|
|
case 'p': scale = "e-12"; break; /* pico */
|
|
case 'n': scale = "e-9"; break; /* nano */
|
|
case 'u': scale = "e-6"; break; /* micro */
|
|
case 'm': scale = "e-3"; break; /* milli */
|
|
case 'k':
|
|
case 'K': scale = "e3"; break; /* kilo */
|
|
case 'M': scale = "e6"; break; /* mega */
|
|
case 'G': scale = "e9"; break; /* giga */
|
|
case 'T': scale = "e12"; break; /* tera */
|
|
default:
|
|
scale = "";
|
|
assert(0);
|
|
break;
|
|
}
|
|
buf[len-1] = 0;
|
|
strcat(buf, scale);
|
|
|
|
/* Convert the exponential string to a real value, */
|
|
result = get_real(buf);
|
|
|
|
free(buf);
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
* Convert a normal number to a real value.
|
|
*/
|
|
double get_real(const char *text)
|
|
{
|
|
double result;
|
|
char *buf = malloc(strlen(text) + 1);
|
|
char *cptr = buf;
|
|
char *end;
|
|
unsigned idx;
|
|
|
|
/* We must have a buffer to remove any '_' characters. */
|
|
assert(buf);
|
|
|
|
/* Remove any '_' characters from the string. */
|
|
for (idx = 0; text[idx]; idx += 1) {
|
|
if (text[idx] == '_') continue;
|
|
*cptr = text[idx];
|
|
cptr += 1;
|
|
}
|
|
*cptr = 0;
|
|
|
|
/* Convert the buffer to a double value and check that the
|
|
* conversion was done successfully. */
|
|
result = strtod(buf, &end);
|
|
assert(*end == 0);
|
|
|
|
free(buf);
|
|
return result;
|
|
}
|
|
|
|
void init_tblmod_lexor(FILE *fp)
|
|
{
|
|
yyrestart(fp);
|
|
}
|
|
|
|
/*
|
|
* Modern version of flex (>=2.5.9) can clean up the scanner data.
|
|
*/
|
|
void destroy_tblmod_lexor(void)
|
|
{
|
|
# ifdef FLEX_SCANNER
|
|
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
|
# if YY_FLEX_MINOR_VERSION > 5 || defined(YY_FLEX_SUBMINOR_VERSION) && YY_FLEX_SUBMINOR_VERSION >= 9
|
|
yylex_destroy();
|
|
# endif
|
|
# endif
|
|
# endif
|
|
}
|