Add parse decorations for expressions.
Elaboration will need a parse tree for expressions. Create one for the expression types that are currently supported. Also add rules and the keywords for all the remaining binary logical operators.
This commit is contained in:
parent
3ca0a482cf
commit
769159d053
|
|
@ -60,7 +60,7 @@ LIBS = @LIBS@ @EXTRALIBS@
|
|||
M = StringHeap.o LineInfo.o
|
||||
|
||||
O = main.o architec.o compiler.o entity.o entity_elaborate.o \
|
||||
lexor.o lexor_keyword.o parse.o vhdlreal.o vhdlint.o $M
|
||||
expression.o lexor.o lexor_keyword.o parse.o vhdlreal.o vhdlint.o debug.o $M
|
||||
|
||||
all: dep vhdlpp@EXEEXT@
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,11 @@
|
|||
*/
|
||||
|
||||
# include "architec.h"
|
||||
# include "expression.h"
|
||||
|
||||
Architecture::Architecture(perm_string name, std::list<Architecture::Statement*>&s)
|
||||
using namespace std;
|
||||
|
||||
Architecture::Architecture(perm_string name, list<Architecture::Statement*>&s)
|
||||
: name_(name)
|
||||
{
|
||||
statements_.splice(statements_.end(), s);
|
||||
|
|
@ -37,11 +40,16 @@ Architecture::Statement::~Statement()
|
|||
{
|
||||
}
|
||||
|
||||
SignalAssignment::SignalAssignment(perm_string targ_name)
|
||||
SignalAssignment::SignalAssignment(perm_string targ_name, list<Expression*>&rv)
|
||||
: target_name_(targ_name)
|
||||
{
|
||||
rval_.splice(rval_.end(), rv);
|
||||
}
|
||||
|
||||
SignalAssignment::~SignalAssignment()
|
||||
{
|
||||
for (list<Expression*>::iterator cur = rval_.begin()
|
||||
; cur != rval_.end() ; ++cur) {
|
||||
delete *cur;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
# include "LineInfo.h"
|
||||
# include <list>
|
||||
|
||||
class Expression;
|
||||
|
||||
/*
|
||||
* The Architecture class carries the contents (name, statements,
|
||||
* etc.) of a parsed VHDL architecture. These objects are ultimately
|
||||
|
|
@ -71,13 +73,14 @@ class Architecture : public LineInfo {
|
|||
class SignalAssignment : public Architecture::Statement {
|
||||
|
||||
public:
|
||||
SignalAssignment(perm_string target_name);
|
||||
SignalAssignment(perm_string target_name, std::list<Expression*>&rval);
|
||||
~SignalAssignment();
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
|
||||
private:
|
||||
perm_string target_name_;
|
||||
std::list<Expression*> rval_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@
|
|||
|
||||
# include "entity.h"
|
||||
# include "architec.h"
|
||||
# include "expression.h"
|
||||
# include <fstream>
|
||||
# include <iomanip>
|
||||
# include <typeinfo>
|
||||
|
||||
static ostream& operator << (ostream&out, port_mode_t that)
|
||||
{
|
||||
|
|
@ -95,5 +97,52 @@ void Architecture::Statement::dump(ostream&out) const
|
|||
void SignalAssignment::dump(ostream&out) const
|
||||
{
|
||||
out << " SignalAssignment file=" << get_fileline() << endl;
|
||||
out << " " << target_name_ << " <= <expr>" << endl;
|
||||
out << " " << target_name_ << " <= <expr>..." << endl;
|
||||
|
||||
for (list<Expression*>::const_iterator cur = rval_.begin()
|
||||
; cur != rval_.end() ; ++cur) {
|
||||
(*cur)->dump(out, 5);
|
||||
}
|
||||
}
|
||||
|
||||
void Expression::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "Expression [" << typeid(*this).name() << "]"
|
||||
<< " at " << get_fileline()<< endl;
|
||||
}
|
||||
|
||||
void ExpLogical::dump(ostream&out, int indent) const
|
||||
{
|
||||
const char*fun_name = "?";
|
||||
switch (fun_) {
|
||||
case AND:
|
||||
fun_name = "AND";
|
||||
break;
|
||||
case OR:
|
||||
fun_name = "OR";
|
||||
break;
|
||||
case NAND:
|
||||
fun_name = "NAND";
|
||||
break;
|
||||
case NOR:
|
||||
fun_name = "NOR";
|
||||
break;
|
||||
case XOR:
|
||||
fun_name = "XOR";
|
||||
break;
|
||||
case XNOR:
|
||||
fun_name = "XNOR";
|
||||
break;
|
||||
}
|
||||
|
||||
out << setw(indent) << "" << "Logical " << fun_name
|
||||
<< " at " << get_fileline() << endl;
|
||||
operand1_->dump(out, indent+4);
|
||||
operand2_->dump(out, indent+4);
|
||||
}
|
||||
|
||||
void ExpName::dump(ostream&out, int indent) const
|
||||
{
|
||||
out << setw(indent) << "" << "ExpName(\"" << name_ << "\")"
|
||||
<< " at " << get_fileline() << endl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2011 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
|
||||
* 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
|
||||
*/
|
||||
|
||||
# include "expression.h"
|
||||
|
||||
Expression::Expression()
|
||||
{
|
||||
}
|
||||
|
||||
Expression::~Expression()
|
||||
{
|
||||
}
|
||||
|
||||
ExpLogical::ExpLogical(ExpLogical::fun_t ty, Expression*op1, Expression*op2)
|
||||
: fun_(ty), operand1_(op1), operand2_(op2)
|
||||
{
|
||||
}
|
||||
|
||||
ExpLogical::~ExpLogical()
|
||||
{
|
||||
delete operand1_;
|
||||
delete operand2_;
|
||||
}
|
||||
|
||||
ExpName::ExpName(perm_string nn)
|
||||
: name_(nn)
|
||||
{
|
||||
}
|
||||
|
||||
ExpName::~ExpName()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
#ifndef __expression_H
|
||||
#define __expression_H
|
||||
/*
|
||||
* Copyright (c) 2011 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
|
||||
* 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
|
||||
*/
|
||||
|
||||
# include "StringHeap.h"
|
||||
# include "LineInfo.h"
|
||||
|
||||
/*
|
||||
* The Expression class represents parsed expressions from the parsed
|
||||
* VHDL input. The Expression class is a virtual class that holds more
|
||||
* specific derived expression types.
|
||||
*/
|
||||
class Expression : public LineInfo {
|
||||
|
||||
public:
|
||||
Expression();
|
||||
virtual ~Expression() =0;
|
||||
|
||||
virtual void dump(ostream&out, int indent) const;
|
||||
|
||||
private:
|
||||
|
||||
private: // Not implemented
|
||||
Expression(const Expression&);
|
||||
Expression& operator = (const Expression&);
|
||||
};
|
||||
|
||||
class ExpLogical : public Expression {
|
||||
|
||||
public:
|
||||
enum fun_t { AND, OR, NAND, NOR, XOR, XNOR };
|
||||
|
||||
public:
|
||||
ExpLogical(ExpLogical::fun_t ty, Expression*op1, Expression*op2);
|
||||
~ExpLogical();
|
||||
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
private:
|
||||
fun_t fun_;
|
||||
Expression*operand1_;
|
||||
Expression*operand2_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The ExpName class represents an expression that is an identifier or
|
||||
* other sort of name.
|
||||
*/
|
||||
class ExpName : public Expression {
|
||||
|
||||
public:
|
||||
ExpName(perm_string nn);
|
||||
~ExpName();
|
||||
|
||||
void dump(ostream&out, int indent) const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
# include "parse_api.h"
|
||||
# include "parse_misc.h"
|
||||
# include "architec.h"
|
||||
# include "expression.h"
|
||||
# include <cstdarg>
|
||||
# include <list>
|
||||
|
||||
|
|
@ -46,9 +47,13 @@ int parse_errors = 0;
|
|||
%union {
|
||||
port_mode_t port_mode;
|
||||
char*text;
|
||||
|
||||
vhdlint* integer;
|
||||
vhdlreal* real;
|
||||
|
||||
Expression*expr;
|
||||
std::list<Expression*>* expr_list;
|
||||
|
||||
InterfacePort*interface_element;
|
||||
std::list<InterfacePort*>* interface_list;
|
||||
|
||||
|
|
@ -98,6 +103,10 @@ int parse_errors = 0;
|
|||
%type <arch_statement> concurrent_statement concurrent_signal_assignment_statement
|
||||
%type <arch_statement_list> architecture_statement_part
|
||||
|
||||
%type <expr> expression expression_logical factor primary relation
|
||||
%type <expr> shift_expression simple_expression term waveform_element
|
||||
|
||||
%type <expr_list> waveform waveform_elements
|
||||
%%
|
||||
|
||||
/* The design_file is the root for the VHDL parse. */
|
||||
|
|
@ -142,11 +151,12 @@ architecture_statement_part
|
|||
concurrent_signal_assignment_statement
|
||||
: IDENTIFIER LEQ waveform ';'
|
||||
{ perm_string targ_name = lex_strings.make($1);
|
||||
SignalAssignment*tmp = new SignalAssignment(targ_name);
|
||||
SignalAssignment*tmp = new SignalAssignment(targ_name, *$3);
|
||||
FILE_NAME(tmp, @1);
|
||||
|
||||
$$ = tmp;
|
||||
delete[]$1;
|
||||
delete $3;
|
||||
}
|
||||
;
|
||||
|
||||
|
|
@ -221,14 +231,43 @@ entity_header
|
|||
|
||||
expression
|
||||
: expression_logical
|
||||
{ $$ = $1; }
|
||||
;
|
||||
|
||||
expression_logical
|
||||
: relation K_and relation
|
||||
{ ExpLogical*tmp = new ExpLogical(ExpLogical::AND, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| relation K_or relation
|
||||
{ ExpLogical*tmp = new ExpLogical(ExpLogical::OR, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| relation K_xor relation
|
||||
{ ExpLogical*tmp = new ExpLogical(ExpLogical::XOR, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| relation K_nand relation
|
||||
{ ExpLogical*tmp = new ExpLogical(ExpLogical::NAND, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| relation K_nor relation
|
||||
{ ExpLogical*tmp = new ExpLogical(ExpLogical::NOR, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| relation K_xnor relation
|
||||
{ ExpLogical*tmp = new ExpLogical(ExpLogical::XNOR, $1, $3);
|
||||
FILE_NAME(tmp, @2);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
factor : primary ;
|
||||
factor : primary { $$ = $1; } ;
|
||||
|
||||
/* The interface_element is also an interface_declaration */
|
||||
interface_element
|
||||
|
|
@ -289,9 +328,14 @@ port_clause
|
|||
|
||||
primary
|
||||
: IDENTIFIER
|
||||
{ ExpName*tmp = new ExpName(lex_strings.make($1));
|
||||
FILE_NAME(tmp, @1);
|
||||
delete[]$1;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
relation : shift_expression ;
|
||||
relation : shift_expression { $$ = $1; } ;
|
||||
|
||||
selected_name
|
||||
: IDENTIFIER '.' K_all
|
||||
|
|
@ -303,11 +347,11 @@ selected_names
|
|||
| selected_name
|
||||
;
|
||||
|
||||
shift_expression : simple_expression ;
|
||||
shift_expression : simple_expression { $$ = $1; } ;
|
||||
|
||||
simple_expression : term ;
|
||||
simple_expression : term { $$ = $1; } ;
|
||||
|
||||
term : factor ;
|
||||
term : factor { $$ = $1; } ;
|
||||
|
||||
use_clause
|
||||
: K_use selected_names ';'
|
||||
|
|
@ -317,17 +361,29 @@ use_clause
|
|||
|
||||
waveform
|
||||
: waveform_elements
|
||||
{ $$ = $1; }
|
||||
| K_unaffected
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
waveform_elements
|
||||
: waveform_elements ',' waveform_element
|
||||
{ std::list<Expression*>*tmp = $1;
|
||||
tmp->push_back($3);
|
||||
$$ = tmp;
|
||||
}
|
||||
| waveform_element
|
||||
{ std::list<Expression*>*tmp = new std::list<Expression*>;
|
||||
tmp->push_back($1);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
waveform_element
|
||||
: expression
|
||||
{ $$ = $1; }
|
||||
| K_null
|
||||
{ $$ = 0; }
|
||||
;
|
||||
|
||||
/* Some keywords are optional in some contexts. In all such cases, a
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
# include "vhdlint.h"
|
||||
# include "vhdlreal.h"
|
||||
# include "architec.h"
|
||||
# include "expression.h"
|
||||
# include "parse.h"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue