Skip to content

Commit

Permalink
Parse real literals and integers with exponents
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Jun 3, 2012
1 parent 1a6b149 commit e3785dd
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 6 deletions.
52 changes: 49 additions & 3 deletions src/lexer.l
Expand Up @@ -27,6 +27,7 @@
#include "util.h"

#include <ctype.h>
#include <math.h>

#define YY_INPUT(buf, result, max_size) { \
result = get_next_char(buf, max_size); \
Expand All @@ -36,11 +37,13 @@

#define YY_USER_ACTION begin_token(yytext);

#define TOKEN(t) return (last_token = (t));
#define TOKEN(t) return (last_token = (t))

static int parse_id(const char *str);
static int parse_ex_id(const char *str);
static int parse_based_int(const char *str);
static int parse_real(const char *str);
static int parse_int(const char *str);
static int resolve_ir1045(void);

static int last_token = -1;
Expand All @@ -55,7 +58,9 @@ STRING \"([^\"]|\"\")*\"
BIT_STRING [BOXbox]\"[0-9a-fA-f_]+\"
CHAR '.'
COMMENT --.*\n
INT [0-9]+
INT [0-9]+{EXPONENT}?
REAL {INT}\.{INT}
EXPONENT [Ee][+-]?[0-9]+
BASED_INT {INT}#[0-9a-fA-f]+#
SPACE [ \t\r\n]+
TICK \'
Expand Down Expand Up @@ -273,8 +278,9 @@ OPEN {O}{P}{E}{N}
"|" { TOKEN(tBAR); }
"[" { TOKEN(tLSQUARE); }
"]" { TOKEN(tRSQUARE); }
{INT} { lvals.ival = atoll(yytext); TOKEN(tINT); }
{INT} { return parse_int(yytext); }
{BASED_INT} { return parse_based_int(yytext); }
{REAL} { return parse_real(yytext); }
{BIT_STRING} { lvals.sval = strdup(yytext); TOKEN(tBITSTRING); }
{STRING} { lvals.sval = strdup(yytext); TOKEN(tSTRING); }
{TICK} { TOKEN(tTICK); }
Expand Down Expand Up @@ -341,6 +347,29 @@ static int parse_ex_id(const char *str)
TOKEN(tID);
}

static int parse_int(const char *str)
{
char *tmp = strdup(str);

char *base = strtok(tmp, "eE");
char *exp = strtok(NULL, "eE");

lvals.ival = atoll(base);

int e = (exp ? atoi(exp) : 0);

free(tmp);

if (e < 0)
TOKEN(tERROR);
else {
for (; e > 0; e--)
lvals.ival *= 10;
}

TOKEN(tINT);
}

static int parse_based_int(const char *str)
{
char *tmp = strdup(str);
Expand All @@ -357,3 +386,20 @@ static int parse_based_int(const char *str)
TOKEN(t);
}

static int parse_real(const char *str)
{
char *tmp = strdup(str);

char *base = strtok(tmp, "eE");
char *exp = strtok(NULL, "eE");

lvals.rval = strtod(base, NULL);

int e = (exp ? atoi(exp) : 0);
if (e != 0)
lvals.rval *= pow(10.0, (double)e);

free(tmp);

TOKEN(tREAL);
}
11 changes: 9 additions & 2 deletions src/parse.y
Expand Up @@ -58,6 +58,7 @@

typedef struct {
int64_t ival;
double rval;
char *sval;
char cval;
} lvals_t;
Expand Down Expand Up @@ -199,7 +200,7 @@
%token tWHILE tLOOP tAFTER tALIAS tATTRIBUTE tPROCEDURE tEXIT
%token tWHEN tCASE tBAR tLSQUARE tRSQUARE tINERTIAL tTRANSPORT
%token tREJECT tBITSTRING tBLOCK tWITH tSELECT tGENERATE tACCESS
%token tFILE tOPEN
%token tFILE tOPEN tREAL

%left tAND tOR tNAND tNOR tXOR tXNOR
%left tEQ tNEQ tLT tLE tGT tGE
Expand Down Expand Up @@ -1952,7 +1953,13 @@ abstract_literal
literal_t l = { { .i = lvals.ival }, .kind = L_INT };
tree_set_literal($$, l);
}
/* | tFLOAT */
| tREAL
{
$$ = tree_new(T_LITERAL);
tree_set_loc($$, &@$);
literal_t l = { { .r = lvals.rval }, .kind = L_REAL };
tree_set_literal($$, l);
}
;

physical_literal
Expand Down
5 changes: 5 additions & 0 deletions test/parse/literal.vhd
Expand Up @@ -4,6 +4,11 @@ architecture a of e is
constant c : integer := 523;
constant a : string := "hel""lo";
constant b : string := """quote""";
constant d : integer := 1E3; -- Integer not real
constant e : real := 1.234;
constant f : real := 0.21712;
constant g : real := 1.4e6;
constant h : real := 235.1e-2;
begin

end architecture;
42 changes: 41 additions & 1 deletion test/test_parse.c
Expand Up @@ -662,7 +662,7 @@ START_TEST(test_literal)
a = parse();
fail_if(a == NULL);
fail_unless(tree_kind(a) == T_ARCH);
fail_unless(tree_decls(a) == 5);
fail_unless(tree_decls(a) == 10);

d = tree_decl(a, 0);
fail_unless(tree_ident(d) == ident_new("POS"));
Expand Down Expand Up @@ -703,6 +703,46 @@ START_TEST(test_literal)
v = tree_value(d);
fail_unless(tree_kind(v) == T_AGGREGATE);

d = tree_decl(a, 5);
fail_unless(tree_ident(d) == ident_new("D"));
v = tree_value(d);
fail_unless(tree_kind(v) == T_LITERAL);
l = tree_literal(v);
fail_unless(l.kind == L_INT);
fail_unless(l.i == 1000);

d = tree_decl(a, 6);
fail_unless(tree_ident(d) == ident_new("E"));
v = tree_value(d);
fail_unless(tree_kind(v) == T_LITERAL);
l = tree_literal(v);
fail_unless(l.kind == L_REAL);
fail_unless(l.r == 1.234);

d = tree_decl(a, 7);
fail_unless(tree_ident(d) == ident_new("F"));
v = tree_value(d);
fail_unless(tree_kind(v) == T_LITERAL);
l = tree_literal(v);
fail_unless(l.kind == L_REAL);
fail_unless(l.r == 0.21712);

d = tree_decl(a, 8);
fail_unless(tree_ident(d) == ident_new("G"));
v = tree_value(d);
fail_unless(tree_kind(v) == T_LITERAL);
l = tree_literal(v);
fail_unless(l.kind == L_REAL);
fail_unless(l.r == 1400000.0);

d = tree_decl(a, 9);
fail_unless(tree_ident(d) == ident_new("H"));
v = tree_value(d);
fail_unless(tree_kind(v) == T_LITERAL);
l = tree_literal(v);
fail_unless(l.kind == L_REAL);
fail_unless(l.r == 2.351);

a = parse();
fail_unless(a == NULL);

Expand Down

0 comments on commit e3785dd

Please sign in to comment.