Merge branch 'cern_20110204'
This commit is contained in:
commit
1cc0f14011
|
|
@ -57,10 +57,10 @@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
|||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@ @EXTRALIBS@
|
||||
|
||||
M = StringHeap.o LineInfo.o
|
||||
M = StringHeap.o LineInfo.o
|
||||
|
||||
O = main.o compiler.o entity.o entity_elaborate.o \
|
||||
lexor.o lexor_keyword.o parse.o $M
|
||||
lexor.o lexor_keyword.o parse.o vhdlreal.o vhdlint.o $M
|
||||
|
||||
all: dep vhdlpp@EXEEXT@
|
||||
|
||||
|
|
|
|||
402
vhdlpp/lexor.lex
402
vhdlpp/lexor.lex
|
|
@ -19,14 +19,24 @@
|
|||
* 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
|
||||
* aint64_t with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
# include "parse_api.h"
|
||||
# include "lexor_keyword.h"
|
||||
# include "vhdlint.h"
|
||||
# include "vhdlreal.h"
|
||||
# include "parse_wrap.h"
|
||||
|
||||
# include <cmath>
|
||||
# include <cassert>
|
||||
# include <iostream>
|
||||
# include <set>
|
||||
|
||||
//class vhdlnum;
|
||||
//class vhdlreal;
|
||||
|
||||
extern int lexor_keyword_code (const char*str, unsigned len);
|
||||
|
||||
/*
|
||||
|
|
@ -38,6 +48,17 @@ extern int lexor_keyword_code (const char*str, unsigned len);
|
|||
*/
|
||||
extern YYLTYPE yylloc;
|
||||
|
||||
static bool are_underscores_correct(char* text);
|
||||
static bool is_based_correct(char* text);
|
||||
static char* escape_quot_and_dup(char* text);
|
||||
static char* escape_apostrophe_and_dup(char* text);
|
||||
|
||||
static double make_double_from_based(char* text);
|
||||
static int64_t make_long_from_based(char* text);
|
||||
|
||||
static int64_t lpow(int64_t left, int64_t right);
|
||||
static unsigned short short_from_hex_char(char ch);
|
||||
|
||||
static char* strdupnew(char const *str)
|
||||
{
|
||||
return str ? strcpy(new char [strlen(str)+1], str) : 0;
|
||||
|
|
@ -51,7 +72,12 @@ static int comment_enter;
|
|||
%x LCOMMENT
|
||||
|
||||
W [ \t\b\f\r]+
|
||||
decimal_literal {integer}(\.{integer})?({exponent})?
|
||||
integer [0-9](_?[0-9])*
|
||||
exponent [eE][-+]?{integer}
|
||||
|
||||
based_literal {integer}#{based_integer}(\.{based_integer})?#{exponent}?
|
||||
based_integer [0-9a-fA-F](_?[0-9a-fA-F])*
|
||||
%%
|
||||
|
||||
[ \t\b\f\r] { ; }
|
||||
|
|
@ -73,10 +99,27 @@ W [ \t\b\f\r]+
|
|||
<CCOMMENT>\n { yylloc.first_line += 1; }
|
||||
<CCOMMENT>"*/" { BEGIN(comment_enter); }
|
||||
|
||||
[a-zA-Z_][a-zA-Z0-9_]* {
|
||||
\'.\' {
|
||||
yylval.text = escape_apostrophe_and_dup(yytext);
|
||||
return CHARACTER_LITERAL;
|
||||
}
|
||||
|
||||
(\"([^"]|(\"\"))*?\")|(\"[^\"]*\") {
|
||||
/* first pattern: string literals with doubled quotation mark */
|
||||
/* second pattern: string literals without doubled quotation */
|
||||
yylval.text = escape_quot_and_dup(yytext);
|
||||
assert(yylval.text);
|
||||
return STRING_LITERAL;
|
||||
}
|
||||
|
||||
[a-zA-Z][a-zA-Z0-9_]* {
|
||||
int rc = lexor_keyword_code(yytext, yyleng);
|
||||
switch (rc) {
|
||||
case IDENTIFIER:
|
||||
if(!are_underscores_correct(yytext))
|
||||
std::cerr << "An invalid underscore in the identifier:"
|
||||
<< yytext << std::endl;
|
||||
//yywarn(yylloc, "An invalid underscore in the identifier");
|
||||
yylval.text = strdupnew(yytext);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -84,11 +127,69 @@ W [ \t\b\f\r]+
|
|||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
\\([^\\]|\\\\)*\\ { /* extended identifiers */
|
||||
yylval.text = strdupnew(yytext);
|
||||
return IDENTIFIER;
|
||||
}
|
||||
|
||||
|
||||
{decimal_literal} {
|
||||
if(!are_underscores_correct(yytext))
|
||||
std::cerr << "An invalid underscore in the decimal literal:"
|
||||
<< yytext << std::endl;
|
||||
|
||||
if(strchr(yytext, '.')) {
|
||||
yylval.real = new vhdlreal(yytext);
|
||||
return REAL_LITERAL;
|
||||
} else {
|
||||
yylval.integer = new vhdlint(yytext);
|
||||
return INT_LITERAL;
|
||||
}
|
||||
}
|
||||
|
||||
{based_literal} {
|
||||
if(!are_underscores_correct(yytext) || !is_based_correct(yytext))
|
||||
std::cerr << "An invalid form of based literal:"
|
||||
<< yytext << std::endl;
|
||||
|
||||
if(strchr(yytext, '.'))
|
||||
{
|
||||
double val = make_double_from_based(yytext);
|
||||
yylval.real = new vhdlreal(val);
|
||||
return REAL_LITERAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
int64_t val = make_long_from_based(yytext);
|
||||
yylval.integer = new vhdlint(val);
|
||||
return INT_LITERAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Compound symbols */
|
||||
"<=" { return LEQ; }
|
||||
">=" { return GEQ; }
|
||||
":=" { return VASSIGN; }
|
||||
"/=" { return NE; }
|
||||
"<>" { return BOX; }
|
||||
"**" { return EXP; }
|
||||
"=>" { return ARROW; }
|
||||
"<<" { return DLT; }
|
||||
">>" { return DGT; }
|
||||
/*
|
||||
Here comes a list of symbols that are more then strange,
|
||||
at least for the time being.
|
||||
|
||||
"??" { return K_CC; }
|
||||
"?=" {}
|
||||
"?/=" {}
|
||||
"?<" {}
|
||||
"?<=" {}
|
||||
"?>" {}
|
||||
"?>=" {}
|
||||
*/
|
||||
|
||||
. { return yytext[0]; }
|
||||
|
||||
|
|
@ -96,6 +197,303 @@ W [ \t\b\f\r]+
|
|||
|
||||
extern void yyparse_set_filepath(const char*path);
|
||||
|
||||
/**
|
||||
* This function checks if underscores in an identifier
|
||||
* or in a number are correct.
|
||||
*
|
||||
* \return true is returned if underscores are placed
|
||||
* correctly according to specification
|
||||
*/
|
||||
static bool are_underscores_correct(char* text)
|
||||
{
|
||||
unsigned char underscore_allowed = 0;
|
||||
const char* cp;
|
||||
for( cp = text; *cp; ++cp)
|
||||
{
|
||||
if (*cp == '_')
|
||||
{
|
||||
if (!underscore_allowed || *(cp+1) == '\0')
|
||||
return 0;
|
||||
underscore_allowed = 0;
|
||||
}
|
||||
else
|
||||
underscore_allowed = 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks if the format of a based number
|
||||
* is correct according to the VHDL standard
|
||||
*
|
||||
* \return true is returned if a based number
|
||||
* is formed well according to specification
|
||||
*/
|
||||
static bool is_based_correct(char* text)
|
||||
{
|
||||
char* ptr;
|
||||
//BASE examination
|
||||
char clean_base[4];
|
||||
clean_base[3] = '\0';
|
||||
char* clean_base_ptr = clean_base;
|
||||
for(ptr = text; ptr != strchr(text, '#'); ++ptr)
|
||||
{
|
||||
if(*ptr == '_')
|
||||
++ptr;
|
||||
if(!(*ptr >= '0' && *ptr <= '9')) //the base uses chars other than digits
|
||||
return 0;
|
||||
if(*clean_base_ptr == '\0')
|
||||
break;
|
||||
*clean_base_ptr = *ptr;
|
||||
++clean_base_ptr;
|
||||
}
|
||||
unsigned length = clean_base_ptr - clean_base;
|
||||
unsigned base;
|
||||
if(length > 2 || length == 0)
|
||||
return 0; //the base is too big or too small
|
||||
if(length == 2)
|
||||
{
|
||||
base = 10*(clean_base[0] - '0') + (clean_base[1] - '0');
|
||||
//the base exceeds 16 or equals 0
|
||||
if(base > 16 || base == 0)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{ //the base consists of one char and is equal to zero
|
||||
base = clean_base[0] - '0';
|
||||
if(base == 0)
|
||||
return 0;
|
||||
}
|
||||
bool point = 0;
|
||||
set<char> allowed_chars;
|
||||
|
||||
unsigned c;
|
||||
if(base <= 10) {
|
||||
for(c = 0; c < base; ++c)
|
||||
allowed_chars.insert(c + '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
for(c = 0; c < 10; ++c)
|
||||
allowed_chars.insert(c + '0');
|
||||
for(c = 0; c < base - 10; ++c)
|
||||
allowed_chars.insert(c + 'a');
|
||||
}
|
||||
//MANTISSA examination
|
||||
for(ptr = strchr(text, '#') + 1, length = 0; ptr != strrchr(text, '#'); ++ptr)
|
||||
{
|
||||
if(*ptr == '.')
|
||||
{
|
||||
//we found a dot and another one was already found
|
||||
if(point == 1)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
//notice the fact of finding a point and continue, without increasing the length
|
||||
point = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//the number consists of other chars than allowed
|
||||
if(allowed_chars.find(*ptr) == allowed_chars.end())
|
||||
return 0;
|
||||
++length;
|
||||
}
|
||||
if(length == 0)
|
||||
return 0;
|
||||
|
||||
//EXPONENT examination
|
||||
if(strchr(text, '\0') - strrchr(text, '#') > 1) { //the number contains an exponent
|
||||
if(*(strrchr(text, '#') + 2) == '-')
|
||||
return 0;
|
||||
length = 0;
|
||||
for(ptr = strrchr(text, '#')+2; *ptr != '\0'; ++ptr)
|
||||
{
|
||||
//the exponent consists of other chars than {'0'.,'9','a'..'f'}
|
||||
if(!((*ptr >= '0' && *ptr <= '9') || (*ptr >= 'a' && *ptr <= 'f')))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes a string literal, gets rid of
|
||||
* quotation marks and copies the remaining characters
|
||||
* to a new persistent C-string
|
||||
*
|
||||
* \return pointer to the new string is returned
|
||||
*/
|
||||
static char* escape_quot_and_dup(char* text)
|
||||
{
|
||||
char* newstr = new char[strlen(text)+1];
|
||||
|
||||
unsigned old_idx, new_idx;
|
||||
for(new_idx = 0, old_idx = 0; old_idx < strlen(text); )
|
||||
{
|
||||
if(text[old_idx] == '"' && old_idx == 0)
|
||||
{ //the beginning of the literal
|
||||
++old_idx;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
if(text[old_idx] == '"' && text[old_idx+1] == '\0')
|
||||
{ //the end
|
||||
newstr[new_idx] = '\0';
|
||||
return newstr;
|
||||
}
|
||||
else
|
||||
if(text[old_idx] == '"' && text[old_idx+1] == '"')
|
||||
{
|
||||
newstr[new_idx++] = '"';
|
||||
old_idx += 2; //jump across two chars
|
||||
}
|
||||
else
|
||||
{
|
||||
newstr[new_idx] = text[old_idx];
|
||||
++old_idx;
|
||||
++new_idx;
|
||||
}
|
||||
}
|
||||
//the function should never reach this point
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes a character literal, gets rid
|
||||
* of the apostrophes and returns new C-string
|
||||
*
|
||||
* \return pointer to the new string is returned
|
||||
*/
|
||||
static char* escape_apostrophe_and_dup(char* text)
|
||||
{
|
||||
char* newstr = new char[2];
|
||||
newstr[0] = text[1];
|
||||
newstr[1] = '\0';
|
||||
return newstr;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes a floating point based number
|
||||
* in form of a C-strings and converts it to a double.
|
||||
*
|
||||
* \return new double is returned
|
||||
*/
|
||||
static double make_double_from_based(char* text)
|
||||
{
|
||||
char* first_hash_ptr = strchr(text, '#');
|
||||
char* second_hash_ptr = strrchr(text, '#');
|
||||
char* last_char_ptr = strchr(text, '\0') - 1;
|
||||
//put null byte in lieu of hashes
|
||||
*first_hash_ptr = '\0';
|
||||
*second_hash_ptr = '\0';
|
||||
|
||||
//now lets deduce the base
|
||||
unsigned base = (unsigned)strtol(text, 0, 10) ;
|
||||
|
||||
double mantissa = 0.0;
|
||||
char*ptr = first_hash_ptr + 1;
|
||||
for( ; ptr != second_hash_ptr ; ++ptr)
|
||||
{
|
||||
if(*ptr == '.')
|
||||
break;
|
||||
if(*ptr != '_')
|
||||
{
|
||||
mantissa = mantissa*base + short_from_hex_char(*ptr);
|
||||
}
|
||||
}
|
||||
double fraction = 0.0;
|
||||
double factor = 1.0/base;
|
||||
for(++ptr ; ptr != second_hash_ptr; ++ptr)
|
||||
{
|
||||
if(*ptr != '_')
|
||||
{
|
||||
fraction = fraction + short_from_hex_char(*ptr)*factor;
|
||||
factor = factor / base;
|
||||
}
|
||||
}
|
||||
if(last_char_ptr == second_hash_ptr) //there is no exponent
|
||||
{
|
||||
return mantissa + fraction;
|
||||
}
|
||||
|
||||
//now calculate the value of the exponent
|
||||
double exponent = 0.0;
|
||||
//leave 'e'/'E' and '+'
|
||||
ptr = *(second_hash_ptr + 2) == '+' ? second_hash_ptr + 3 : second_hash_ptr + 2;
|
||||
|
||||
for( ; *ptr != '\0'; ++ptr)
|
||||
{
|
||||
if(*ptr != '_')
|
||||
{
|
||||
exponent = exponent*base + short_from_hex_char(*ptr);
|
||||
}
|
||||
}
|
||||
return pow(mantissa + fraction, exponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes a hexadecimal digit in form of
|
||||
* a char and returns its litteral value as short
|
||||
*/
|
||||
static unsigned short short_from_hex_char(char ch)
|
||||
{
|
||||
if(ch >= '0' && ch <= '9')
|
||||
return ch - '0';
|
||||
else
|
||||
return ch - 'a' + 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes a based number in form of
|
||||
* a C-strings and converts it to a int64_t.
|
||||
*
|
||||
* \return new double is returned
|
||||
*/
|
||||
static int64_t make_long_from_based(char* text) {
|
||||
char* first_hash_ptr = strchr(text, '#');
|
||||
char* second_hash_ptr = strrchr(text, '#');
|
||||
char* end_ptr = strrchr(text, '\0');
|
||||
//now lets deduce the base
|
||||
*first_hash_ptr = '\0';
|
||||
unsigned base = (unsigned)strtol(text, 0, 10) ;
|
||||
|
||||
char *ptr = first_hash_ptr + 1;
|
||||
int64_t mantissa = 0;
|
||||
for( ; ptr != second_hash_ptr ; ++ptr)
|
||||
{
|
||||
if(*ptr != '_')
|
||||
{
|
||||
mantissa = mantissa * base + short_from_hex_char(*ptr);
|
||||
}
|
||||
}
|
||||
//if there is an exponent
|
||||
if(end_ptr - second_hash_ptr > 1)
|
||||
{
|
||||
int64_t exponent = 0L;
|
||||
|
||||
ptr = *(second_hash_ptr + 2) == '+' ? second_hash_ptr + 3 : second_hash_ptr + 2;
|
||||
for( ; *ptr != '\0'; ++ptr)
|
||||
{
|
||||
if(*ptr != '_')
|
||||
exponent = base*exponent + short_from_hex_char(*ptr);
|
||||
}
|
||||
return lpow(mantissa, exponent);
|
||||
}
|
||||
else
|
||||
return mantissa;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive power function for int64_t
|
||||
*/
|
||||
static int64_t lpow(int64_t left, int64_t right) {
|
||||
if(right == 0)
|
||||
return 1;
|
||||
else
|
||||
return left*lpow(left, right - 1);
|
||||
}
|
||||
|
||||
void reset_lexor(FILE*fd, const char*path)
|
||||
{
|
||||
yylloc.text = path;
|
||||
|
|
|
|||
|
|
@ -18,19 +18,114 @@ struct lexor_keyword { const char*name; int mask; int tokenType; };
|
|||
%%
|
||||
abs, GN_KEYWORD_2008, K_abs
|
||||
access, GN_KEYWORD_2008, K_access
|
||||
after, GN_KEYWORD_2008, K_after
|
||||
alias, GN_KEYWORD_2008, K_alias
|
||||
all, GN_KEYWORD_2008, K_all
|
||||
and, GN_KEYWORD_2008, K_and
|
||||
architecture, GN_KEYWORD_2008, K_architecture
|
||||
array, GN_KEYWORD_2008, K_array
|
||||
assert, GN_KEYWORD_2008, K_assert
|
||||
attribute, GN_KEYWORD_2008, K_attribute
|
||||
begin, GN_KEYWORD_2008, K_begin
|
||||
block, GN_KEYWORD_2008, K_block
|
||||
body, GN_KEYWORD_2008, K_body
|
||||
buffer, GN_KEYWORD_2008, K_buffer
|
||||
bus, GN_KEYWORD_2008, K_bus
|
||||
case, GN_KEYWORD_2008, K_case
|
||||
component, GN_KEYWORD_2008, K_component
|
||||
configuration, GN_KEYWORD_2008, K_configuration
|
||||
constant, GN_KEYWORD_2008, K_constant
|
||||
context, GN_KEYWORD_2008, K_context
|
||||
cover, GN_KEYWORD_2008, K_cover
|
||||
default, GN_KEYWORD_2008, K_default
|
||||
disconnect, GN_KEYWORD_2008, K_disconnect
|
||||
downto, GN_KEYWORD_2008, K_downto
|
||||
else, GN_KEYWORD_2008, K_else
|
||||
elsif GN_KEYWORD_2008, K_elsif
|
||||
end, GN_KEYWORD_2008, K_end
|
||||
entity, GN_KEYWORD_2008, K_entity
|
||||
exit, GN_KEYWORD_2008, K_exit
|
||||
fairness, GN_KEYWORD_2008, K_fairness
|
||||
file, GN_KEYWORD_2008, K_file
|
||||
for, GN_KEYWORD_2008, K_for
|
||||
force, GN_KEYWORD_2008, K_force
|
||||
function, GN_KEYWORD_2008, K_function
|
||||
generate, GN_KEYWORD_2008, K_generate
|
||||
generic, GN_KEYWORD_2008, K_generic
|
||||
group, GN_KEYWORD_2008, K_group
|
||||
guarded, GN_KEYWORD_2008, K_guarded
|
||||
if, GN_KEYWORD_2008, K_if
|
||||
impure, GN_KEYWORD_2008, K_impure
|
||||
in, GN_KEYWORD_2008, K_in
|
||||
inertial, GN_KEYWORD_2008, K_inertial
|
||||
inout, GN_KEYWORD_2008, K_inout
|
||||
is, GN_KEYWORD_2008, K_is
|
||||
label, GN_KEYWORD_2008, K_label
|
||||
library, GN_KEYWORD_2008, K_library
|
||||
linkage, GN_KEYWORD_2008, K_linkage
|
||||
literal, GN_KEYWORD_2008, K_literal
|
||||
loop, GN_KEYWORD_2008, K_loop
|
||||
map, GN_KEYWORD_2008, K_map
|
||||
mod, GN_KEYWORD_2008, K_mod
|
||||
nand, GN_KEYWORD_2008, K_nand
|
||||
new, GN_KEYWORD_2008, K_new
|
||||
next, GN_KEYWORD_2008, K_next
|
||||
nor, GN_KEYWORD_2008, K_nor
|
||||
not, GN_KEYWORD_2008, K_not
|
||||
null, GN_KEYWORD_2008, K_null
|
||||
of, GN_KEYWORD_2008, K_of
|
||||
on, GN_KEYWORD_2008, K_on
|
||||
or, GN_KEYWORD_2008, K_or
|
||||
others, GN_KEYWORD_2008, K_others
|
||||
out, GN_KEYWORD_2008, K_out
|
||||
package, GN_KEYWORD_2008, K_package
|
||||
port, GN_KEYWORD_2008, K_port
|
||||
postponed, GN_KEYWORD_2008, K_postponed
|
||||
procedure, GN_KEYWORD_2008, K_procedure
|
||||
process, GN_KEYWORD_2008, K_process
|
||||
property, GN_KEYWORD_2008, K_property
|
||||
protected, GN_KEYWORD_2008, K_protected
|
||||
pure, GN_KEYWORD_2008, K_pure
|
||||
range, GN_KEYWORD_2008, K_range
|
||||
record, GN_KEYWORD_2008, K_record
|
||||
register, GN_KEYWORD_2008, K_register
|
||||
reject, GN_KEYWORD_2008, K_reject
|
||||
release, GN_KEYWORD_2008, K_release
|
||||
rem, GN_KEYWORD_2008, K_rem
|
||||
report, GN_KEYWORD_2008, K_report
|
||||
restrict, GN_KEYWORD_2008, K_restrict
|
||||
return, GN_KEYWORD_2008, K_return
|
||||
rol, GN_KEYWORD_2008, K_rol
|
||||
ror, GN_KEYWORD_2008, K_ror
|
||||
select, GN_KEYWORD_2008, K_select
|
||||
sequence, GN_KEYWORD_2008, K_sequence
|
||||
severity, GN_KEYWORD_2008, K_severity
|
||||
signal, GN_KEYWORD_2008, K_signal
|
||||
shared, GN_KEYWORD_2008, K_shared
|
||||
sla, GN_KEYWORD_2008, K_sla
|
||||
sll, GN_KEYWORD_2008, K_sll
|
||||
sra, GN_KEYWORD_2008, K_sra
|
||||
srl, GN_KEYWORD_2008, K_srl
|
||||
strong, GN_KEYWORD_2008, K_strong
|
||||
subtype, GN_KEYWORD_2008, K_subtype
|
||||
then, GN_KEYWORD_2008, K_then
|
||||
to, GN_KEYWORD_2008, K_to
|
||||
transport, GN_KEYWORD_2008, K_transport
|
||||
type, GN_KEYWORD_2008, K_type
|
||||
unaffected, GN_KEYWORD_2008, K_unaffected
|
||||
units. GN_KEYWORD_2008, K_units
|
||||
until, GN_KEYWORD_2008, K_until
|
||||
use, GN_KEYWORD_2008, K_use
|
||||
variable, GN_KEYWORD_2008, K_variable
|
||||
vmode, GN_KEYWORD_2008, K_vmode
|
||||
vprop, GN_KEYWORD_2008, K_vprop
|
||||
vunit, GN_KEYWORD_2008, K_vunit
|
||||
wait, GN_KEYWORD_2008, K_wait
|
||||
when, GN_KEYWORD_2008, K_when
|
||||
while, GN_KEYWORD_2008, K_while
|
||||
with, GN_KEYWORD_2008, K_with
|
||||
xnor, GN_KEYWORD_2008, K_xnor
|
||||
xor, GN_KEYWORD_2008, K_xor
|
||||
%%
|
||||
|
||||
int lexor_keyword_mask = GN_KEYWORD_2008;
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@
|
|||
*/
|
||||
|
||||
# include "vhdlpp_config.h"
|
||||
# include "vhdlint.h"
|
||||
# include "vhdlreal.h"
|
||||
# include "compiler.h"
|
||||
# include "parse_api.h"
|
||||
# include <string.h>
|
||||
# include <string.h>
|
||||
# include <cstdarg>
|
||||
# include <list>
|
||||
|
||||
|
|
@ -39,10 +41,13 @@ static void errormsg(const YYLTYPE&loc, const char*msg, ...);
|
|||
int parse_errors = 0;
|
||||
%}
|
||||
|
||||
|
||||
%union {
|
||||
port_mode_t port_mode;
|
||||
char*text;
|
||||
|
||||
vhdlint* integer;
|
||||
vhdlreal* real;
|
||||
|
||||
InterfacePort*interface_element;
|
||||
std::list<InterfacePort*>* interface_list;
|
||||
};
|
||||
|
|
@ -52,11 +57,11 @@ int parse_errors = 0;
|
|||
%token K_array K_assert K_assume K_assume_guarantee K_attribute
|
||||
%token K_begin K_block K_body K_buffer K_bus
|
||||
%token K_case K_component K_configuration K_constant K_context K_cover
|
||||
%token K_default K_disconect K_downto
|
||||
%token K_default K_disconnect K_downto
|
||||
%token K_else K_elsif K_end K_entity K_exit
|
||||
%token K_fairness K_file K_for K_force K_function
|
||||
%token K_generate K_generic K_group K_guarded
|
||||
%token K_if K_impure K_in K_internal K_inout K_is
|
||||
%token K_if K_impure K_in K_inertial K_inout K_is
|
||||
%token K_label K_library K_linkage K_literal K_loop
|
||||
%token K_map K_mod
|
||||
%token K_nand K_new K_next K_nor K_not K_null
|
||||
|
|
@ -65,8 +70,8 @@ int parse_errors = 0;
|
|||
%token K_property K_protected K_pure
|
||||
%token K_range K_record K_register K_reject K_release K_rem K_report
|
||||
%token K_restrict K_restrict_guarantee K_return K_rol K_ror
|
||||
%token K_select K_sequence K_seerity K_signal K_shared
|
||||
%token K_sla K_sll K_sra K_srl K_string K_subtype
|
||||
%token K_select K_sequence K_severity K_signal K_shared
|
||||
%token K_sla K_sll K_sra K_srl K_strong K_subtype
|
||||
%token K_then K_to K_transport K_type
|
||||
%token K_unaffected K_units K_until K_use
|
||||
%token K_variable K_vmode K_vprop K_vunit
|
||||
|
|
@ -74,8 +79,11 @@ int parse_errors = 0;
|
|||
%token K_xnor K_xor
|
||||
/* Identifiers that are not keywords are identifiers. */
|
||||
%token <text> IDENTIFIER
|
||||
%token <integer> INT_LITERAL
|
||||
%token <real> REAL_LITERAL
|
||||
%token <text> STRING_LITERAL CHARACTER_LITERAL
|
||||
/* compound symbols */
|
||||
%token LEQ GEQ VASSIGN
|
||||
%token LEQ GEQ VASSIGN NE BOX EXP ARROW DLT DGT
|
||||
|
||||
/* The rules may have types. */
|
||||
%type <interface_element> interface_element
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
*/
|
||||
|
||||
# include <list>
|
||||
# include "vhdlint.h"
|
||||
# include "vhdlreal.h"
|
||||
# include "parse.h"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
#include "config.h"
|
||||
#include "vhdlint.h"
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
bool vhdlint::is_negative() const
|
||||
{
|
||||
return value_ < 0L;
|
||||
}
|
||||
|
||||
bool vhdlint::is_positive() const
|
||||
{
|
||||
return value_ > 0L;
|
||||
}
|
||||
|
||||
bool vhdlint::is_zero() const
|
||||
{
|
||||
return value_ == 0L;
|
||||
}
|
||||
|
||||
vhdlint::vhdlint(const char* text)
|
||||
{
|
||||
unsigned text_length = strlen(text);
|
||||
if(text_length == 0)
|
||||
{
|
||||
value_ = 0L;
|
||||
return;
|
||||
}
|
||||
|
||||
char* new_text = new char[text_length + 1];
|
||||
|
||||
const char* ptr;
|
||||
char* new_ptr;
|
||||
for(ptr = text, new_ptr = new_text; *ptr != '\0'; ++ptr)
|
||||
{
|
||||
if(*ptr == '_')
|
||||
continue;
|
||||
else
|
||||
{
|
||||
*new_ptr = *ptr;
|
||||
++new_ptr;
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
*new_ptr = '\0';
|
||||
|
||||
istringstream str(new_text);
|
||||
delete[] new_text;
|
||||
|
||||
//TODO: check if numbers greater than MAX_INT are handled correctly
|
||||
str >> value_;
|
||||
}
|
||||
|
||||
vhdlint::vhdlint(const int64_t& val)
|
||||
{
|
||||
value_ = val;
|
||||
}
|
||||
|
||||
vhdlint::vhdlint(const vhdlint& val)
|
||||
{
|
||||
value_ = val.as_long();
|
||||
}
|
||||
|
||||
int64_t vhdlint::as_long() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef __vhdlint_H
|
||||
#define __vhdlint_H
|
||||
|
||||
#include "config.h"
|
||||
#include <stdint.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class vhdlint
|
||||
{
|
||||
public:
|
||||
explicit vhdlint(const char* text);
|
||||
explicit vhdlint(const int64_t& val);
|
||||
explicit vhdlint(const vhdlint& val);
|
||||
|
||||
bool is_negative() const;
|
||||
bool is_positive() const;
|
||||
bool is_zero() const;
|
||||
|
||||
int64_t as_long() const;
|
||||
//vhdlv get(const unsigned index) const;
|
||||
//void set(const unsigned index, const unsigned val);
|
||||
// unsigned short operator[](const unsigned index);
|
||||
private:
|
||||
int64_t value_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef __vhdlnum_H
|
||||
#define __vhdlnum_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#warning vhdlnum
|
||||
|
||||
class vhdlnum {
|
||||
public:
|
||||
vhdlnum(char* text) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
#include "config.h"
|
||||
#include "compiler.h"
|
||||
#include "vhdlreal.h"
|
||||
#include <assert.h>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
vhdlreal::vhdlreal() {
|
||||
value_ = 0.0;
|
||||
}
|
||||
|
||||
vhdlreal::vhdlreal(const double& r) {
|
||||
value_ = r;
|
||||
}
|
||||
|
||||
vhdlreal::vhdlreal(const vhdlreal& val) {
|
||||
value_ = val.as_double();
|
||||
}
|
||||
|
||||
vhdlreal::vhdlreal(const char* text) {
|
||||
assert(strlen(text) != 0);
|
||||
char* buffer = new char[strlen(text)+1];
|
||||
|
||||
char* buf_ptr;
|
||||
for(buf_ptr = buffer; *text != 0; ++buf_ptr, ++text) {
|
||||
if(*text == '_')
|
||||
continue;
|
||||
*buf_ptr = *text;
|
||||
}
|
||||
*buf_ptr = '\0';
|
||||
|
||||
value_ = strtod(buffer, NULL);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
ostream& operator<< (ostream& str, const vhdlreal& r) {
|
||||
return (str << r.as_double());
|
||||
}
|
||||
vhdlreal operator+ (const vhdlreal& r1, const vhdlreal& r2) {
|
||||
return vhdlreal(r1.as_double() + r2.as_double());
|
||||
}
|
||||
vhdlreal operator- (const vhdlreal& r1, const vhdlreal& r2) {
|
||||
return vhdlreal(r1.as_double() - r2.as_double());
|
||||
}
|
||||
vhdlreal operator* (const vhdlreal& r1, const vhdlreal& r2) {
|
||||
return vhdlreal(r1.as_double() * r2.as_double());
|
||||
}
|
||||
vhdlreal operator/ (const vhdlreal& r1, const vhdlreal& r2) {
|
||||
return vhdlreal(r1.as_double() / r2.as_double());
|
||||
}
|
||||
vhdlreal operator% (const vhdlreal& r1, const vhdlreal& r2) {
|
||||
return vhdlreal(fmod(r1.as_double(), r2.as_double()));
|
||||
}
|
||||
vhdlreal pow(const vhdlreal& r1, const vhdlreal& r2) {
|
||||
return vhdlreal(pow(r1.as_double(), r2.as_double()));
|
||||
}
|
||||
vhdlreal operator- (const vhdlreal& r) {
|
||||
return vhdlreal(-r.as_double());
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef __vhdlreal_h
|
||||
#define __vhdlreal_h
|
||||
|
||||
#include "config.h"
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
using namespace std;
|
||||
/*
|
||||
* This class holds a floating point decimal number. The number is
|
||||
* stored as double. All based numbers are converted by an external
|
||||
* function to a double and then stored as class instance.
|
||||
*/
|
||||
class vhdlreal
|
||||
{
|
||||
public:
|
||||
friend ostream& operator<< (ostream&, const vhdlreal&);
|
||||
friend vhdlreal operator+ (const vhdlreal&, const vhdlreal&);
|
||||
friend vhdlreal operator- (const vhdlreal&, const vhdlreal&);
|
||||
friend vhdlreal operator* (const vhdlreal&, const vhdlreal&);
|
||||
friend vhdlreal operator/ (const vhdlreal&, const vhdlreal&);
|
||||
friend vhdlreal operator% (const vhdlreal&, const vhdlreal&);
|
||||
friend vhdlreal pow(const vhdlreal&, const vhdlreal&);
|
||||
// Unary minus.
|
||||
friend vhdlreal operator- (const vhdlreal&);
|
||||
|
||||
explicit vhdlreal();
|
||||
explicit vhdlreal(const char*text);
|
||||
explicit vhdlreal(const double& val);
|
||||
vhdlreal(const vhdlreal& val);
|
||||
virtual ~vhdlreal() {};
|
||||
|
||||
double as_double() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
protected:
|
||||
double value_;
|
||||
};
|
||||
#endif
|
||||
Loading…
Reference in New Issue