Permalink
Browse files

Parse file declarations

  • Loading branch information...
1 parent 1381a93 commit d29cb3316902b4d06a64dfc4871ca6f26d53bf09 @nickg committed May 6, 2012
Showing with 137 additions and 15 deletions.
  1. +2 −0 src/lexer.l
  2. +59 −7 src/parse.y
  3. +40 −4 src/tree.c
  4. +9 −3 src/tree.h
  5. +6 −0 test/parse/types.vhd
  6. +21 −1 test/test_parse.c
View
@@ -163,6 +163,7 @@ SELECT {S}{E}{L}{E}{C}{T}
GENERATE {G}{E}{N}{E}{R}{A}{T}{E}
ACCESS {A}{C}{C}{E}{S}{S}
FILE {F}{I}{L}{E}
+OPEN {O}{P}{E}{N}
%%
@@ -246,6 +247,7 @@ FILE {F}{I}{L}{E}
{GENERATE} { TOKEN(tGENERATE); }
{ACCESS} { TOKEN(tACCESS); }
{FILE} { TOKEN(tFILE); }
+{OPEN} { TOKEN(tOPEN); }
"(" { TOKEN(tLPAREN); }
")" { TOKEN(tRPAREN); }
View
@@ -172,7 +172,7 @@
%type <l> sensitivity_clause process_sensitivity_clause attr_decl
%type <l> package_body_decl_item package_body_decl_part subprogram_decl_part
%type <l> subprogram_decl_item waveform alias_decl attr_spec
-%type <l> conditional_waveforms component_decl
+%type <l> conditional_waveforms component_decl file_decl
%type <p> entity_header generate_body
%type <g> id_list context_item context_clause selected_id_list use_clause
%type <m> opt_mode
@@ -199,7 +199,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
+%token tFILE tOPEN
%left tAND tOR tNAND tNOR tXOR tXNOR
%left tEQ tNEQ tLT tLE tGT tGE
@@ -385,9 +385,9 @@ package_decl_item
| attr_decl
| attr_spec
| component_decl
+| file_decl
/* | signal_declaration
| shared_variable_declaration
- | file_declaration
| disconnection_specification
| use_clause
| group_template_declaration
@@ -443,16 +443,68 @@ block_decl_item
| attr_decl
| attr_spec
| component_decl
+| file_decl
/* | subprogram_body
| shared_variable_declaration
- | file_declaration
| configuration_specification
| disconnection_specification
| use_clause
| group_template_declaration
| group_declaration */
;
+file_decl
+: tFILE id_list tCOLON subtype_indication tOPEN expr tIS expr tSEMI
+ {
+ $$ = NULL;
+ for (list_t *it = $2; it != NULL; it = it->next) {
+ tree_t t = tree_new(T_FILE_DECL);
+ tree_set_ident(t, it->item.ident);
+ tree_set_type(t, $4);
+ tree_set_file_mode(t, $6);
+ tree_set_value(t, $8);
+ tree_set_loc(t, &@$);
+
+ tree_list_append(&$$, t);
+ }
+
+ list_free($2);
+ }
+| tFILE id_list tCOLON subtype_indication tIS expr tSEMI
+ {
+ tree_t m = tree_new(T_REF);
+ tree_set_ident(m, ident_new("READ_MODE"));
+
+ $$ = NULL;
+ for (list_t *it = $2; it != NULL; it = it->next) {
+ tree_t t = tree_new(T_FILE_DECL);
+ tree_set_ident(t, it->item.ident);
+ tree_set_type(t, $4);
+ tree_set_value(t, $6);
+ tree_set_file_mode(t, m);
+ tree_set_loc(t, &@$);
+
+ tree_list_append(&$$, t);
+ }
+
+ list_free($2);
+ }
+| tFILE id_list tCOLON subtype_indication tSEMI
+ {
+ $$ = NULL;
+ for (list_t *it = $2; it != NULL; it = it->next) {
+ tree_t t = tree_new(T_FILE_DECL);
+ tree_set_ident(t, it->item.ident);
+ tree_set_type(t, $4);
+ tree_set_loc(t, &@$);
+
+ tree_list_append(&$$, t);
+ }
+
+ list_free($2);
+ }
+;
+
component_decl
: tCOMPONENT id opt_is generic_clause port_clause tEND
tCOMPONENT opt_id tSEMI
@@ -845,8 +897,8 @@ process_decl_item
| alias_decl
| attr_decl
| attr_spec
+| file_decl
/* | subprogram_body
- | file_declaration
| use_clause
| group_template_declaration
| group_declaration
@@ -987,8 +1039,8 @@ subprogram_decl_item
| alias_decl
| attr_decl
| attr_spec
- /* | file_declaration
- | use_clause
+| file_decl
+ /* | use_clause
| group_template_declaration
| group_declaration */
;
View
@@ -90,6 +90,7 @@ struct tree {
tree_t target; // T_VAR_ASSIGN, T_SIGNAL_ASSIGN
tree_t ref; // T_REF, T_FCALL, T_ARRAY_REF, T_PCALL
tree_t severity; // T_ASSERT
+ tree_t file_mode; // T_FILE_DECL
unsigned pos; // T_ENUM_LIT
};
union {
@@ -148,7 +149,7 @@ struct tree_rd_ctx {
|| IS(t, T_TYPE_DECL) || IS(t, T_CONST_DECL) \
|| IS(t, T_FUNC_DECL) || IS(t, T_FUNC_BODY) || IS(t, T_ALIAS) \
|| IS(t, T_ATTR_DECL) || IS(t, T_ATTR_SPEC) || IS(t, T_PROC_DECL) \
- || IS(t, T_PROC_BODY) || IS(t, T_COMPONENT))
+ || IS(t, T_PROC_BODY) || IS(t, T_COMPONENT) || IS(t, T_FILE_DECL))
#define IS_EXPR(t) \
(IS(t, T_FCALL) || IS(t, T_LITERAL) || IS(t, T_REF) \
|| IS(t, T_QUALIFIED) || IS(t, T_AGGREGATE) || IS(t, T_ATTR_REF) \
@@ -174,7 +175,7 @@ struct tree_rd_ctx {
|| IS(t, T_PROC_DECL) || IS(t, T_PROC_BODY) || IS(t, T_EXIT) \
|| IS(t, T_PCALL) || IS(t, T_CASE) || IS(t, T_BLOCK) \
|| IS(t, T_SELECT) || IS(t, T_COMPONENT) || IS(t, T_IF_GENERATE) \
- || IS(t, T_FOR_GENERATE))
+ || IS(t, T_FOR_GENERATE) || IS(t, T_FILE_DECL))
#define HAS_IDENT2(t) \
(IS(t, T_ARCH) || IS(t, T_ATTR_REF) || IS(t, T_INSTANCE) \
|| IS(t, T_FOR) || IS(t, T_ATTR_SPEC) || IS(t, T_PCALL) \
@@ -188,7 +189,7 @@ struct tree_rd_ctx {
|| IS(t, T_TYPE_DECL) || IS_EXPR(t) || IS(t, T_ENUM_LIT) \
|| IS(t, T_CONST_DECL) || IS(t, T_FUNC_DECL) \
|| IS(t, T_FUNC_BODY) || IS(t, T_ALIAS) || IS(t, T_ATTR_DECL) \
- || IS(t, T_PROC_DECL) || IS(t, T_PROC_BODY))
+ || IS(t, T_PROC_DECL) || IS(t, T_PROC_BODY) || IS(t, T_FILE_DECL))
#define HAS_PARAMS(t) \
(IS(t, T_FCALL) || IS(t, T_ATTR_REF) || IS(t, T_ARRAY_REF) \
|| IS(t, T_INSTANCE) || IS(t, T_PCALL) || IS(t, T_CONCAT) \
@@ -215,7 +216,7 @@ struct tree_rd_ctx {
|| IS(t, T_ARRAY_SLICE) || IS(t, T_IF) || IS(t, T_RETURN) \
|| IS(t, T_WHILE) || IS(t, T_ALIAS) || IS(t, T_ATTR_SPEC) \
|| IS(t, T_EXIT) || IS(t, T_COND) || IS(t, T_SELECT) \
- || IS(t, T_IF_GENERATE))
+ || IS(t, T_IF_GENERATE) || IS(t, T_FILE_DECL))
#define HAS_CONTEXT(t) \
(IS(t, T_ARCH) || IS(t, T_ENTITY) || IS(t, T_PACKAGE) \
|| IS(t, T_PACK_BODY) || IS(t, T_ELAB))
@@ -1098,6 +1099,23 @@ void tree_set_reject(tree_t t, tree_t r)
t->reject = r;
}
+tree_t tree_file_mode(tree_t t)
+{
+ assert(t != NULL);
+ assert(IS(t, T_FILE_DECL));
+
+ return t->file_mode;
+}
+
+void tree_set_file_mode(tree_t t, tree_t m)
+{
+ assert(t != NULL);
+ assert(m != NULL);
+ assert(IS(t, T_FILE_DECL));
+
+ t->file_mode = m;
+}
+
uint32_t tree_index(tree_t t)
{
assert(t != NULL);
@@ -1321,6 +1339,8 @@ static unsigned tree_visit_aux(tree_t t, tree_visit_fn_t fn, void *context,
n += tree_visit_p(&t->genmaps, fn, context, kind, generation, deep);
else if (IS(t, T_IF))
n += tree_visit_a(&t->elses, fn, context, kind, generation, deep);
+ else if (IS(t, T_FILE_DECL))
+ n += tree_visit_aux(t->file_mode, fn, context, kind, generation, deep);
if (deep) {
for (unsigned i = 0; i < t->n_attrs; i++) {
@@ -1640,6 +1660,10 @@ void tree_write(tree_t t, tree_wr_ctx_t ctx)
write_a(&t->elses, ctx);
break;
+ case T_FILE_DECL:
+ tree_write(t->file_mode, ctx);
+ break;
+
default:
break;
}
@@ -1810,6 +1834,10 @@ tree_t tree_read(tree_rd_ctx_t ctx)
read_a(&t->elses, ctx);
break;
+ case T_FILE_DECL:
+ t->file_mode = tree_read(ctx);
+ break;
+
default:
break;
}
@@ -2130,6 +2158,10 @@ static tree_t tree_rewrite_aux(tree_t t, struct rewrite_ctx *ctx)
rewrite_a(&t->elses, ctx);
break;
+ case T_FILE_DECL:
+ tree_set_file_mode(t, tree_rewrite_aux(t->file_mode, ctx));
+ break;
+
default:
break;
}
@@ -2332,6 +2364,10 @@ static tree_t tree_copy_aux(tree_t t, struct tree_copy_ctx *ctx)
copy_a(&t->elses, &copy->elses, ctx);
break;
+ case T_FILE_DECL:
+ copy->file_mode = tree_copy_aux(t->file_mode, ctx);
+ break;
+
default:
break;
}
View
@@ -91,6 +91,7 @@ typedef enum tree_kind {
T_COMPONENT,
T_IF_GENERATE,
T_FOR_GENERATE,
+ T_FILE_DECL,
T_LAST_TREE_KIND
} tree_kind_t;
@@ -141,7 +142,8 @@ const loc_t *tree_loc(tree_t t);
void tree_set_loc(tree_t t, const loc_t *loc);
// T_PORT_DECL, T_SIGNAL_DECL, T_VAR_DECL, T_REF, T_TYPE_DECL,
-// T_CONST_DECL, T_FUNC_DECL, T_ALIAS, T_ATTR_DECL, T_TYPE_CONV
+// T_CONST_DECL, T_FUNC_DECL, T_ALIAS, T_ATTR_DECL, T_TYPE_CONV,
+// T_FILE_DECL
type_t tree_type(tree_t t);
void tree_set_type(tree_t t, type_t ty);
bool tree_has_type(tree_t t);
@@ -150,7 +152,7 @@ bool tree_has_type(tree_t t);
// T_VAR_DECL, T_REF, T_TYPE_DECL, T_PACKAGE, T_QUALIFIED, T_ENUM_LIT,
// T_CONST_DECL, T_FUNC_DECL, T_ATTR_REF, T_INSTANCE, T_WHILE,
// T_ATTR_DECL, T_PCALL, T_TYPE_CONV, T_COMPONENT, T_IF_GENERATE,
-// T_FOR_GENERATE
+// T_FOR_GENERATE, T_FILE_DECL
ident_t tree_ident(tree_t t);
void tree_set_ident(tree_t t, ident_t i);
bool tree_has_ident(tree_t t);
@@ -169,6 +171,10 @@ void tree_add_port(tree_t t, tree_t d);
port_mode_t tree_port_mode(tree_t t);
void tree_set_port_mode(tree_t t, port_mode_t mode);
+// T_FILE_DECL
+tree_t tree_file_mode(tree_t t);
+void tree_set_file_mode(tree_t t, tree_t m);
+
// T_ENTITY, T_COMPONENT
unsigned tree_generics(tree_t t);
tree_t tree_generic(tree_t t, unsigned n);
@@ -191,7 +197,7 @@ void tree_set_literal(tree_t t, literal_t lit);
// T_PORT_DECL, T_SIGNAL_DECL, T_VAR_DECL, T_VAR_ASSIGN,
// T_QUALIFIED, T_CONST_DECL, T_ASSERT, T_ATTR_SPEC
// T_ARRAY_REF, T_IF, T_WHILE, T_REF, T_ALIAS, T_WAVEFORM
-// T_COND, T_SELECT, T_IF_GENERATE
+// T_COND, T_SELECT, T_IF_GENERATE, T_FILE_DECL
bool tree_has_value(tree_t t);
tree_t tree_value(tree_t t);
void tree_set_value(tree_t t, tree_t v);
View
@@ -21,6 +21,12 @@ architecture a of b is
type p is access my_int;
type f is file of my_int;
+
+ file f1 : f open READ_MODE is "foo";
+
+ file f2 : f is "bar";
+
+ file f3 : f;
begin
end architecture;
View
@@ -536,7 +536,7 @@ START_TEST(test_types)
a = parse();
fail_if(a == NULL);
fail_unless(tree_kind(a) == T_ARCH);
- fail_unless(tree_decls(a) == 10);
+ fail_unless(tree_decls(a) == 13);
d = tree_decl(a, 0);
fail_unless(tree_kind(d) == T_TYPE_DECL);
@@ -625,6 +625,26 @@ START_TEST(test_types)
fail_unless(type_kind(type_file(t)) == T_UNRESOLVED);
fail_unless(type_ident(type_file(t)) == ident_new("MY_INT"));
+ d = tree_decl(a, 10);
+ fail_unless(tree_kind(d) == T_FILE_DECL);
+ fail_unless(tree_ident(d) == ident_new("F1"));
+ fail_unless(tree_has_value(d));
+ fail_unless(tree_kind(tree_value(d)) == T_AGGREGATE);
+ fail_unless(tree_kind(tree_file_mode(d)) == T_REF);
+
+ d = tree_decl(a, 11);
+ fail_unless(tree_kind(d) == T_FILE_DECL);
+ fail_unless(tree_ident(d) == ident_new("F2"));
+ fail_unless(tree_has_value(d));
+ fail_unless(tree_kind(tree_value(d)) == T_AGGREGATE);
+ fail_unless(tree_kind(tree_file_mode(d)) == T_REF);
+ fail_unless(tree_ident(tree_file_mode(d)) == ident_new("READ_MODE"));
+
+ d = tree_decl(a, 12);
+ fail_unless(tree_kind(d) == T_FILE_DECL);
+ fail_unless(tree_ident(d) == ident_new("F3"));
+ fail_if(tree_has_value(d));
+
a = parse();
fail_unless(a == NULL);

0 comments on commit d29cb33

Please sign in to comment.