1 //
2 //  Copyright (C) 2014-2019  Nick Gasson
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 //
17 
18 #include "util.h"
19 #include "phase.h"
20 #include "token.h"
21 #include "common.h"
22 
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <stdarg.h>
29 #include <ctype.h>
30 #include <assert.h>
31 #include <stdbool.h>
32 #include <stdlib.h>
33 #include <limits.h>
34 
35 typedef struct {
36    token_t  token;
37    yylval_t lval;
38    loc_t    loc;
39 } tokenq_t;
40 
41 typedef struct {
42    token_t look[4];
43    token_t stop[4];
44    token_t abort;
45    token_t nest_in;
46    token_t nest_out;
47    int     depth;
48 } look_params_t;
49 
50 typedef struct cond_state cond_state_t;
51 
52 struct cond_state {
53    cond_state_t *next;
54    bool          result;
55    loc_t         loc;
56 };
57 
58 static const char   *perm_linebuf = NULL;
59 static ident_t       perm_file_name = NULL;
60 static int           n_token_next_start = 0;
61 static int           n_row = 0;
62 static bool          last_was_newline = true;
63 static loc_t         start_loc;
64 static loc_t         last_loc;
65 static const char   *read_ptr;
66 static const char   *file_start;
67 static size_t        file_sz;
68 static int           n_errors = 0;
69 static const char   *hint_str = NULL;
70 static int           n_correct = 0;
71 static tokenq_t     *tokenq;
72 static int           tokenq_sz;
73 static int           tokenq_head;
74 static int           tokenq_tail;
75 static yylval_t      last_lval;
76 static token_t       opt_hist[8];
77 static int           nopt_hist = 0;
78 static cond_state_t *cond_state = NULL;
79 static bool          translate_on = true;
80 static bool          parse_pragmas = false;
81 
82 loc_t yylloc;
83 int yylex(void);
84 
85 #define scan(...) _scan(1, __VA_ARGS__, -1)
86 #define expect(...) _expect(1, __VA_ARGS__, -1)
87 #define one_of(...) _one_of(1, __VA_ARGS__, -1)
88 #define not_at_token(...) ((peek() != tEOF) && !_scan(1, __VA_ARGS__, -1))
89 #define peek() peek_nth(1)
90 
91 #define parse_error(loc, ...) do {            \
92       if (n_correct >= RECOVER_THRESH) {      \
93          error_at(loc, __VA_ARGS__);          \
94          n_errors++;                          \
95       }                                       \
96    } while (0)
97 
98 #define RECOVER_THRESH 5
99 #define TRACE_PARSE    0
100 #define WARN_LOOKAHEAD 0
101 #define TRACE_RECOVERY 0
102 
103 #define STD(x, y) (standard() >= (STD_##x) ? y : -1)
104 
105 #if TRACE_PARSE
106 static int depth = 0;
107 #endif
108 
109 typedef void (*add_func_t)(tree_t, tree_t);
110 
111 typedef struct {
112    const char *old_hint;
113    loc_t       old_start_loc;
114 } state_t;
115 
116 #define EXTEND(s)                                                      \
117    __attribute__((cleanup(_pop_state))) const state_t _state =         \
118       { hint_str, start_loc };                                         \
119    hint_str = s;                                                       \
120    _push_state(&_state);
121 
122 #define BEGIN(s)                                                       \
123    EXTEND(s);                                                          \
124    start_loc = LOC_INVALID;
125 
126 #define CURRENT_LOC _diff_loc(&start_loc, &last_loc)
127 
128 static tree_t p_expression(void);
129 static tree_t p_sequential_statement(void);
130 static tree_t p_concurrent_statement(void);
131 static tree_t p_subprogram_declaration(tree_t spec);
132 static tree_t p_subprogram_body(tree_t spec);
133 static tree_t p_subprogram_specification(void);
134 static tree_t p_name(void);
135 static tree_t p_block_configuration(void);
136 static tree_t p_protected_type_body(void);
137 static bool p_cond_analysis_expr(void);
138 
139 static bool consume(token_t tok);
140 static bool optional(token_t tok);
141 
_pop_state(const state_t * s)142 static void _pop_state(const state_t *s)
143 {
144 #if TRACE_PARSE
145    depth--;
146    for (int i = 0; i < depth; i++)
147       printf(" ");
148    printf("<-- %s\n", hint_str);
149 #endif
150    hint_str  = s->old_hint;
151    if (s->old_start_loc.first_line != LINE_INVALID)
152       start_loc = s->old_start_loc;
153 }
154 
_push_state(const state_t * s)155 static void _push_state(const state_t *s)
156 {
157 #if TRACE_PARSE
158    for (int i = 0; i < depth; i++)
159       printf(" ");
160    printf("--> %s\n", hint_str);
161    depth++;
162 #endif
163 }
164 
token_str(token_t tok)165 static const char *token_str(token_t tok)
166 {
167    static const char *token_strs[] = {
168       "end of file", "identifier", "entity", "is", "end", "generic", "port",
169       "constant", "component", "configuration", "architecture", "of", "begin",
170       "for", "type", "to", "all", "in", "out", "buffer", "bus", "unaffected",
171       "signal", "downto", "process", "postponed", "wait", "report", "(", ")",
172       ";", ":=", ":", ",", "integer", "string", "error", "inout", "linkage",
173       "variable", "if", "range", "subtype", "units", "package", "library",
174       "use", ".", "null", "'", "function", "impure", "return", "pure", "array",
175       "<>", "=>", "others", "assert", "severity", "on", "map", "then", "else",
176       "elsif", "body", "while", "loop", "after", "alias", "attribute",
177       "procedure", "exit", "next", "when", "case", "label", "group", "literal",
178       "|", "[", "]", "inertial", "transport", "reject", "bit string", "block",
179       "with", "select", "generate", "access", "file", "open", "real", "until",
180       "record", "new", "shared", "and", "or", "nand", "nor", "xor", "xnor",
181       "=", "/=", "<", "<=", ">", ">=", "+", "-", "&", "**", "/", "sll", "srl",
182       "sla", "sra", "rol", "ror", "mod", "rem", "abs", "not", "*", "guarded",
183       "reverse_range", "protected", "context", "`if", "`else", "`elsif", "`end",
184       "`error", "`warning", "translate_off", "translate_on", "pragma"
185    };
186 
187    if ((size_t)tok >= ARRAY_LEN(token_strs))
188       return "???";
189    else
190       return token_strs[tok];
191 }
192 
conditional_yylex(void)193 static token_t conditional_yylex(void)
194 {
195    const token_t token = yylex();
196 
197 #if 0
198    printf("%s %s\n", (cond_state ? (cond_state->result ? "1" : "0") : "-"),
199           token_str(token));
200 #endif
201 
202    switch (token) {
203    case tCONDIF:
204       {
205          BEGIN("conditional analysis directive");
206 
207          cond_state_t *new = xmalloc(sizeof(cond_state_t));
208          new->loc    = yylloc;
209          new->result = p_cond_analysis_expr();
210          new->next   = cond_state;
211 
212          consume(tTHEN);
213 
214          new->loc.last_column = yylloc.last_column;
215          new->loc.last_line   = yylloc.last_line;
216 
217          cond_state = new;
218          return conditional_yylex();
219       }
220 
221    case tCONDELSE:
222       {
223          BEGIN("conditional analysis directive");
224 
225          if (cond_state == NULL)
226             parse_error(&yylloc, "unexpected $yellow$%s$$ outside conditional "
227                         "analysis block", token_str(token));
228          else
229             cond_state->result = !(cond_state->result);
230 
231          return conditional_yylex();
232       }
233 
234    case tCONDEND:
235       {
236          BEGIN("conditional analysis directive");
237 
238          if (cond_state == NULL)
239             parse_error(&yylloc, "unexpected $yellow$%s$$ outside conditional "
240                         "analysis block", token_str(token));
241          else {
242             cond_state_t *old = cond_state;
243             cond_state = cond_state->next;
244             free(old);
245          }
246 
247          optional(tIF);
248 
249          return conditional_yylex();
250       }
251 
252    case tCONDERROR:
253    case tCONDWARN:
254       {
255          if (cond_state == NULL || cond_state->result) {
256             BEGIN("conditional analysis directive");
257 
258             loc_t loc = yylloc;
259             if (consume(tSTRING)) {
260                loc.last_column = yylloc.last_column;
261                loc.last_line   = yylloc.last_line;
262 
263                if (token == tCONDWARN)
264                   warn_at(&loc, "%s", last_lval.s);
265                else
266                   parse_error(&loc, "%s", last_lval.s);
267 
268                free(last_lval.s);
269             }
270          }
271 
272          return conditional_yylex();
273       }
274 
275    case tSYNTHOFF:
276       {
277          BEGIN("synthesis translate_off");
278 
279          if (opt_get_int("synthesis"))
280             translate_on = false;
281 
282          return conditional_yylex();
283       }
284 
285    case tSYNTHON:
286       {
287          BEGIN("synthesis translate_off");
288 
289          translate_on = true;
290          return conditional_yylex();
291       }
292 
293    case tEOF:
294       if (cond_state != NULL) {
295          parse_error(&(cond_state->loc), "unterminated conditional "
296                      "analysis block");
297          n_correct = 0;
298       }
299       return tEOF;
300 
301    default:
302       if (translate_on && (cond_state == NULL || cond_state->result)) {
303          if (token == tPRAGMA && !parse_pragmas)
304             return conditional_yylex();
305          else
306             return token;
307       }
308       else
309          return conditional_yylex();
310    }
311 }
312 
peek_nth(int n)313 static token_t peek_nth(int n)
314 {
315    while (((tokenq_head - tokenq_tail) & (tokenq_sz - 1)) < n) {
316       // Calling conditional_yylex may recursively call this function
317       const token_t token = conditional_yylex();
318 
319       int next = (tokenq_head + 1) & (tokenq_sz - 1);
320       if (unlikely(next == tokenq_tail)) {
321          const int newsz = tokenq_sz * 2;
322          tokenq_t *new = xmalloc(newsz * sizeof(tokenq_t));
323 
324          tokenq_t *p = new;
325          for (int i = tokenq_tail; i != tokenq_head;
326               i = (i + 1) & (tokenq_sz - 1))
327             *p++ = tokenq[i];
328 
329          free(tokenq);
330 
331          tokenq      = new;
332          tokenq_sz   = newsz;
333          tokenq_head = p - new;
334          tokenq_tail = 0;
335 
336          next = (tokenq_head + 1) & (tokenq_sz - 1);
337       }
338 
339       extern yylval_t yylval;
340 
341       tokenq[tokenq_head].token = token;
342       tokenq[tokenq_head].lval  = yylval;
343       tokenq[tokenq_head].loc   = yylloc;
344 
345       tokenq_head = next;
346    }
347 
348    const int pos = (tokenq_tail + n - 1) & (tokenq_sz - 1);
349    return tokenq[pos].token;
350 }
351 
look_for(const look_params_t * params)352 static bool look_for(const look_params_t *params)
353 {
354    bool found = false;
355    token_t tok = -1;
356    int n, nest = 0;
357    for (n = 1; ;) {
358       tok = peek_nth(n++);
359       if ((tok == tEOF) || (tok == params->abort))
360          goto stop_looking;
361       else if (tok == params->nest_in)
362          nest++;
363 
364       if (nest == params->depth) {
365          for (int i = 0; i < ARRAY_LEN(params->look); i++) {
366             if (tok == params->look[i]) {
367                found = true;
368                goto stop_looking;
369             }
370          }
371 
372          for (int i = 0; i < ARRAY_LEN(params->stop); i++) {
373             if (tok == params->stop[i])
374                goto stop_looking;
375          }
376       }
377 
378       if (tok == params->nest_out)
379          nest--;
380    }
381  stop_looking:
382 
383 #if WARN_LOOKAHEAD > 0
384    if (n >= WARN_LOOKAHEAD)
385       warn_at(&(tokenq[tokenq_tail].loc), "look ahead depth %d", n);
386 #endif
387 
388    return found;
389 }
390 
drop_token(void)391 static void drop_token(void)
392 {
393    assert(tokenq_head != tokenq_tail);
394 
395    if (start_loc.last_line == LINE_INVALID)
396       start_loc = tokenq[tokenq_tail].loc;
397 
398    last_lval = tokenq[tokenq_tail].lval;
399    last_loc  = tokenq[tokenq_tail].loc;
400 
401    tokenq_tail = (tokenq_tail + 1) & (tokenq_sz - 1);
402 
403    nopt_hist = 0;
404 }
405 
drop_tokens_until(token_t tok)406 static void drop_tokens_until(token_t tok)
407 {
408    token_t next;
409    do {
410       next = peek();
411       drop_token();
412    } while ((tok != next) && (next != tEOF));
413 
414 #if TRACE_RECOVERY
415    if (peek() != tEOF)
416       fmt_loc(stdout, &(tokenq[tokenq_tail].loc));
417 #endif
418 }
419 
_vexpect(va_list ap)420 static void _vexpect(va_list ap)
421 {
422    LOCAL_TEXT_BUF tb = tb_new();
423 
424    tb_printf(tb, "unexpected $yellow$%s$$ while parsing %s, "
425              "expecting ", token_str(peek()), hint_str);
426 
427    bool first = true;
428 
429    for (int i = 0; i < nopt_hist; i++) {
430       if (first)
431          tb_printf(tb, "one of ");
432       else
433          tb_printf(tb, ", ");
434 
435       tb_printf(tb, "$yellow$%s$$", token_str(opt_hist[i]));
436 
437       first = false;
438    }
439 
440    int tok = va_arg(ap, int);
441    while (tok != -1) {
442       const int tmp = tok;
443       tok = va_arg(ap, int);
444 
445       if (first && (tok != -1))
446          tb_printf(tb, "one of ");
447       else if (!first)
448          tb_printf(tb, (tok == -1) ? " or " : ", ");
449 
450       tb_printf(tb, "$yellow$%s$$", token_str(tmp));
451 
452       first = false;
453    }
454 
455    if (n_correct >= RECOVER_THRESH) {
456       error_at(&(tokenq[tokenq_tail].loc), "%s", tb_get(tb));
457       n_errors++;
458    }
459 
460    n_correct = 0;
461 
462    drop_token();
463 }
464 
_expect(int dummy,...)465 static void _expect(int dummy, ...)
466 {
467    va_list ap;
468    va_start(ap, dummy);
469    _vexpect(ap);
470    va_end(ap);
471 }
472 
consume(token_t tok)473 static bool consume(token_t tok)
474 {
475    const token_t got = peek();
476    if (tok != got) {
477       expect(tok);
478       return false;
479    }
480    else {
481       n_correct++;
482       drop_token();
483       return true;
484    }
485 }
486 
optional(token_t tok)487 static bool optional(token_t tok)
488 {
489    if (peek() == tok) {
490       consume(tok);
491       return true;
492    }
493    else {
494       if (nopt_hist < ARRAY_LEN(opt_hist))
495          opt_hist[nopt_hist++] = tok;
496       return false;
497    }
498 }
499 
_scan(int dummy,...)500 static bool _scan(int dummy, ...)
501 {
502    va_list ap;
503    va_start(ap, dummy);
504 
505    token_t p = peek();
506    bool found = false;
507 
508    while (!found) {
509       const int tok = va_arg(ap, token_t);
510       if (tok == -1)
511          break;
512       else if (p == tok)
513          found = true;
514    }
515 
516    va_end(ap);
517    return found;
518 }
519 
_one_of(int dummy,...)520 static int _one_of(int dummy, ...)
521 {
522    va_list ap;
523    va_start(ap, dummy);
524 
525    token_t p = peek();
526    bool found = false;
527 
528    while (!found) {
529       const int tok = va_arg(ap, token_t);
530       if (tok == -1)
531          break;
532       else if (p == tok)
533          found = true;
534    }
535 
536    va_end(ap);
537 
538    if (found) {
539       consume(p);
540       return p;
541    }
542    else {
543       va_start(ap, dummy);
544       _vexpect(ap);
545       va_end(ap);
546 
547       return -1;
548    }
549 }
550 
_diff_loc(const loc_t * start,const loc_t * end)551 static const loc_t *_diff_loc(const loc_t *start, const loc_t *end)
552 {
553    static loc_t result;
554 
555    result.first_line   = start->first_line;
556    result.first_column = start->first_column;
557    result.last_line    = end->last_line;
558    result.last_column  = end->last_column;
559    result.file         = start->file;
560    result.linebuf      = start->linebuf;
561 
562    return &result;
563 }
564 
loc_to_ident(const loc_t * loc)565 static ident_t loc_to_ident(const loc_t *loc)
566 {
567    char sbuf[64];
568    checked_sprintf(sbuf, sizeof(sbuf), "line_%d", loc->first_line);
569 
570    if (!ident_interned(sbuf))
571       return ident_new(sbuf);
572 
573    LOCAL_TEXT_BUF tb = tb_new();
574    tb_printf(tb, "%sa", sbuf);
575 
576    for (int i = 1; ident_interned(tb_get(tb)); i++) {
577       if (i % 26 != 0)
578          tb_backup(tb, 1);
579       tb_append(tb, 'a' + i % 26);
580    }
581 
582    return ident_new(tb_get(tb));
583 }
584 
set_label_and_loc(tree_t t,ident_t label,const loc_t * loc)585 static void set_label_and_loc(tree_t t, ident_t label, const loc_t *loc)
586 {
587    tree_set_loc(t, loc);
588 
589    if (label == NULL)
590       label = loc_to_ident(loc);
591 
592    tree_set_ident(t, label);
593 }
594 
bit_str_to_literal(const char * str,const loc_t * loc)595 static tree_t bit_str_to_literal(const char *str, const loc_t *loc)
596 {
597    tree_t t = tree_new(T_LITERAL);
598    tree_set_loc(t, loc);
599    tree_set_subkind(t, L_STRING);
600 
601    char base_ch = str[0];
602    int base;
603    switch (base_ch) {
604    case 'X': case 'x': base = 16; break;
605    case 'O': case 'o': base = 8;  break;
606    case 'B': case 'b': base = 2;  break;
607    default:
608       parse_error(loc, "invalid base '%c' for bit string", base_ch);
609       return t;
610    }
611 
612    tree_t one = tree_new(T_REF);
613    tree_set_ident(one, ident_new("'1'"));
614    tree_set_loc(one, loc);
615 
616    tree_t zero = tree_new(T_REF);
617    tree_set_ident(zero, ident_new("'0'"));
618    tree_set_loc(zero, loc);
619 
620    for (const char *p = str + 2; *p != '\"'; p++) {
621       if (*p == '_')
622          continue;
623 
624       int n = (isdigit((int)*p) ? (*p - '0')
625                : 10 + (isupper((int)*p) ? (*p - 'A') : (*p - 'a')));
626 
627       if (n >= base) {
628          parse_error(loc, "invalid digit '%c' in bit string", *p);
629          return t;
630       }
631 
632       for (int d = (base >> 1); d > 0; n = n % d, d >>= 1)
633          tree_add_char(t, (n / d) ? one : zero);
634    }
635 
636    return t;
637 }
638 
get_time(int64_t fs)639 static tree_t get_time(int64_t fs)
640 {
641    tree_t lit = tree_new(T_LITERAL);
642    tree_set_subkind(lit, L_INT);
643    tree_set_ival(lit, fs);
644 
645    tree_t unit = tree_new(T_REF);
646    tree_set_ident(unit, ident_new("FS"));
647 
648    tree_t f = tree_new(T_FCALL);
649    tree_set_ident(f, ident_new("\"*\""));
650 
651    tree_t left = tree_new(T_PARAM);
652    tree_set_subkind(left, P_POS);
653    tree_set_value(left, lit);
654 
655    tree_t right = tree_new(T_PARAM);
656    tree_set_subkind(right, P_POS);
657    tree_set_value(right, unit);
658 
659    tree_add_param(f, left);
660    tree_add_param(f, right);
661 
662    return f;
663 }
664 
int_to_physical(tree_t t,tree_t unit)665 static tree_t int_to_physical(tree_t t, tree_t unit)
666 {
667    tree_t ref = tree_new(T_REF);
668    tree_set_ident(ref, tree_ident(unit));
669 
670    tree_t fcall = tree_new(T_FCALL);
671    tree_set_loc(fcall, tree_loc(t));
672    tree_set_ident(fcall, ident_new("\"*\""));
673 
674    tree_t a = tree_new(T_PARAM);
675    tree_set_subkind(a, P_POS);
676    tree_set_value(a, t);
677 
678    tree_t b = tree_new(T_PARAM);
679    tree_set_subkind(b, P_POS);
680    tree_set_value(b, ref);
681 
682    tree_add_param(fcall, a);
683    tree_add_param(fcall, b);
684 
685    return fcall;
686 }
687 
set_delay_mechanism(tree_t t,tree_t reject)688 static void set_delay_mechanism(tree_t t, tree_t reject)
689 {
690    if (reject == NULL) {
691       // Inertial delay with same value as waveform
692       // LRM 93 section 8.4 the rejection limit in this case is
693       // specified by the time expression of the first waveform
694       tree_t w = (tree_kind(t) == T_CASSIGN
695                   ? tree_waveform(tree_cond(t, 0), 0)
696                   : tree_waveform(t, 0));
697       if (tree_has_delay(w))
698          tree_set_reject(t, tree_delay(w));
699    }
700    else
701       tree_set_reject(t, reject);
702 }
703 
get_cond_analysis_identifier(const char * name)704 static const char *get_cond_analysis_identifier(const char *name)
705 {
706    if (strcmp(name, "VHDL_VERSION") == 0)
707       return standard_text(standard());
708    else if (strcmp(name, "TOOL_TYPE") == 0)
709       return "SIMULATION";
710    else if (strcmp(name, "TOOL_VENDOR") == 0)
711       return PACKAGE_URL;
712    else if (strcmp(name, "TOOL_NAME") == 0)
713       return PACKAGE_NAME;
714    else if (strcmp(name, "TOOL_EDITION") == 0)
715       return "";
716    else if (strcmp(name, "TOOL_VERSION") == 0)
717       return PACKAGE_VERSION;
718    else
719       return NULL;
720 }
721 
p_cond_analysis_relation(void)722 static bool p_cond_analysis_relation(void)
723 {
724    // (  conditional_analysis_expression )
725    //   | not ( conditional_analysis_expression )
726    //   | conditional_analysis_identifier = string_literal
727    //   | conditional_analysis_identifier /= string_literal
728    //   | conditional_analysis_identifier < string_literal
729    //   | conditional_analysis_identifier <= string_literal
730    //   | conditional_analysis_identifier > string_literal
731    //   | conditional_analysis_identifier >= string_literal
732 
733    BEGIN("conditional analysis relation");
734 
735    bool result = false;
736    switch (one_of(tLPAREN, tNOT, tID)) {
737    case tLPAREN:
738       result = p_cond_analysis_expr();
739       consume(tRPAREN);
740       break;
741 
742    case tNOT:
743       result = !p_cond_analysis_expr();
744       break;
745 
746    case tID:
747       {
748          char *name = last_lval.s;
749          token_t rel = one_of(tEQ, tNEQ, tLT, tLE, tGT, tGE);
750 
751          if (consume(tSTRING)) {
752             const char *value = get_cond_analysis_identifier(name);
753             if (value == NULL)
754                parse_error(CURRENT_LOC, "undefined conditional analysis "
755                            "identifier %s", name);
756             else {
757                char *cmp = last_lval.s + 1;
758                cmp[strlen(cmp) - 1] = '\0';
759 
760                switch (rel) {
761                case tEQ:
762                   result = strcmp(value, cmp) == 0;
763                   break;
764                case tNEQ:
765                   result = strcmp(value, cmp) != 0;
766                   break;
767                case tLT:
768                   result = strcmp(value, cmp) < 0;
769                   break;
770                case tLE:
771                   result = strcmp(value, cmp) <= 0;
772                   break;
773                case tGT:
774                   result = strcmp(value, cmp) > 0;
775                   break;
776                case tGE:
777                   result = strcmp(value, cmp) >= 0;
778                   break;
779                default:
780                   break;
781                }
782             }
783 
784             free(last_lval.s);
785          }
786 
787          free(name);
788       }
789       break;
790    }
791 
792    return result;
793 }
794 
p_cond_analysis_expr(void)795 static bool p_cond_analysis_expr(void)
796 {
797    // conditional_analysis_relation
798    //   | conditional_analysis_relation { and conditional_analysis_relation }
799    //   | conditional_analysis_relation { or conditional_analysis_relation }
800    //   | conditional_analysis_relation { xor conditional_analysis_relation }
801    //   | conditioanl_analysis_relation { xnor conditional_analysis_relation }
802 
803    BEGIN("conditional analysis expression");
804 
805    const bool lhs = p_cond_analysis_relation();
806 
807    switch (peek()) {
808    case tAND:
809       consume(tAND);
810       return p_cond_analysis_relation() && lhs;
811    case tOR:
812       consume(tOR);
813       return p_cond_analysis_relation() || lhs;
814    case tXOR:
815       consume(tXOR);
816       return p_cond_analysis_relation() ^ lhs;
817    case tXNOR:
818       consume(tXNOR);
819       return !(p_cond_analysis_relation() ^ lhs);
820    default:
821       return lhs;
822    }
823 }
824 
p_identifier(void)825 static ident_t p_identifier(void)
826 {
827    // basic_identifier | extended_identifier
828 
829    if (consume(tID)) {
830       char *s = last_lval.s;
831       ident_t i = ident_new(s);
832       free(s);
833       return i;
834    }
835    else
836       return ident_new("error");
837 }
838 
p_selected_identifier(void)839 static ident_t p_selected_identifier(void)
840 {
841    // identifier { . identifier }
842 
843    ident_t id = p_identifier();
844    while (optional(tDOT))
845       id = ident_prefix(id, p_identifier(), '.');
846 
847    return id;
848 }
849 
p_identifier_list(void)850 static ident_list_t *p_identifier_list(void)
851 {
852    // identifier { , identifier }
853 
854    ident_list_t *result = NULL;
855 
856    ident_list_add(&result, p_identifier());
857 
858    while (optional(tCOMMA))
859       ident_list_push(&result, p_identifier());
860 
861    return result;
862 }
863 
p_operator_symbol(void)864 static ident_t p_operator_symbol(void)
865 {
866    // string_literal
867 
868    consume(tSTRING);
869 
870    char *s = last_lval.s;
871    for (char *p = s; *p != '\0'; p++)
872       *p = tolower((int)*p);
873    ident_t id = ident_new(s);
874    free(s);
875 
876    return id;
877 }
878 
p_library_clause(tree_t unit)879 static void p_library_clause(tree_t unit)
880 {
881    // library logical_name_list ;
882 
883    BEGIN("library clause");
884 
885    consume(tLIBRARY);
886 
887    LOCAL_IDENT_LIST ids = p_identifier_list();
888 
889    consume(tSEMI);
890 
891    for (ident_list_t *it = ids; it != NULL; it = it->next) {
892       tree_t l = tree_new(T_LIBRARY);
893       tree_set_ident(l, it->ident);
894       tree_set_loc(l, CURRENT_LOC);
895 
896       tree_add_context(unit, l);
897    }
898 }
899 
p_use_clause(tree_t unit,add_func_t addf)900 static void p_use_clause(tree_t unit, add_func_t addf)
901 {
902    // use selected_name { , selected_name } ;
903 
904    // TODO: the structure of this is a hangover from the old Bison parser
905 
906    BEGIN("use clause");
907 
908    consume(tUSE);
909 
910    do {
911       tree_t u = tree_new(T_USE);
912 
913       ident_t i1 = p_identifier();
914       consume(tDOT);
915 
916       switch (peek()) {
917       case tID:
918          tree_set_ident(u, ident_prefix(i1, p_identifier(), '.'));
919 
920          if (optional(tDOT)) {
921             switch (peek()) {
922             case tID:
923                tree_set_ident2(u, p_identifier());
924                break;
925 
926             case tSTRING:
927                tree_set_ident2(u, p_operator_symbol());
928                break;
929 
930             case tALL:
931                consume(tALL);
932                tree_set_ident2(u, all_i);
933                break;
934 
935             default:
936                expect(tID, tSTRING, tALL);
937             }
938          }
939          break;
940 
941       case tALL:
942          consume(tALL);
943          tree_set_ident(u, i1);
944          tree_set_ident2(u, all_i);
945          break;
946 
947       default:
948          expect(tID, tALL);
949       }
950 
951       tree_set_loc(u, CURRENT_LOC);
952       (*addf)(unit, u);
953    } while (optional(tCOMMA));
954 
955    consume(tSEMI);
956 }
957 
p_context_reference(tree_t unit)958 static void p_context_reference(tree_t unit)
959 {
960    // context selected_name { , selected_name } ;
961 
962    BEGIN("context reference");
963 
964    consume(tCONTEXT);
965 
966    do {
967       tree_t c = tree_new(T_CTXREF);
968       tree_set_ident(c, p_selected_identifier());
969       tree_set_loc(c, CURRENT_LOC);
970 
971       tree_add_context(unit, c);
972    } while (optional(tCOMMA));
973 
974    consume(tSEMI);
975 }
976 
p_pragma(void)977 static tree_t p_pragma(void)
978 {
979    // A pragma is a special comment such as
980    //     -- lint_off ....
981    // The contents of the comment are stored in a special T_PRAGMA node for
982    // processing by external tools.
983 
984    consume(tPRAGMA);
985 
986    extern char *yytext;
987 
988    tree_t pragma = tree_new(T_PRAGMA);
989    tree_set_text(pragma, yytext);
990    return pragma;
991 }
992 
p_context_item(tree_t unit)993 static void p_context_item(tree_t unit)
994 {
995    // library_clause | use_clause | 2008: context_reference
996 
997    BEGIN("context item");
998 
999    switch (peek()) {
1000    case tLIBRARY:
1001       p_library_clause(unit);
1002       break;
1003 
1004    case tUSE:
1005       p_use_clause(unit, tree_add_context);
1006       break;
1007 
1008    case tCONTEXT:
1009       p_context_reference(unit);
1010       break;
1011 
1012    case tPRAGMA:
1013       tree_add_context(unit, p_pragma());
1014       break;
1015 
1016    default:
1017       expect(tLIBRARY, tUSE, tCONTEXT);
1018    }
1019 }
1020 
p_context_clause(tree_t unit)1021 static void p_context_clause(tree_t unit)
1022 {
1023    // { context_item }
1024 
1025    BEGIN("context clause");
1026 
1027    while (scan(tLIBRARY, tUSE, tCONTEXT, tPRAGMA)) {
1028       if (peek() == tCONTEXT && peek_nth(3) == tIS)
1029          break;
1030       else
1031          p_context_item(unit);
1032    }
1033 }
1034 
p_mode(void)1035 static port_mode_t p_mode(void)
1036 {
1037    // in | out | inout | buffer | linkage
1038 
1039    switch (one_of(tIN, tOUT, tINOUT, tBUFFER, tLINKAGE)) {
1040    case tIN:
1041       return PORT_IN;
1042    case tOUT:
1043       return PORT_OUT;
1044    case tINOUT:
1045       return PORT_INOUT;
1046    case tBUFFER:
1047       return PORT_BUFFER;
1048    case tLINKAGE:
1049       return PORT_LINKAGE;
1050    default:
1051       return PORT_INVALID;
1052    }
1053 }
1054 
p_range(tree_t left)1055 static range_t p_range(tree_t left)
1056 {
1057    // attribute_name | simple_expression direction simple_expression
1058 
1059    EXTEND("range");
1060 
1061    range_t r = {};
1062 
1063    switch (one_of(tTO, tDOWNTO)) {
1064    case tTO:
1065       r.kind  = RANGE_TO;
1066       r.left  = left;
1067       r.right = p_expression();
1068       break;
1069 
1070    case tDOWNTO:
1071       r.kind  = RANGE_DOWNTO;
1072       r.left  = left;
1073       r.right = p_expression();
1074       break;
1075    }
1076 
1077    return r;
1078 }
1079 
p_range_constraint(void)1080 static tree_t p_range_constraint(void)
1081 {
1082    // range range
1083 
1084    BEGIN("range constraint");
1085 
1086    consume(tRANGE);
1087 
1088    tree_t t = tree_new(T_CONSTRAINT);
1089    tree_set_subkind(t, C_RANGE);
1090 
1091    tree_t expr1 = p_expression();
1092    switch (peek()) {
1093    case tTO:
1094    case tDOWNTO:
1095       tree_add_range(t, p_range(expr1));
1096       break;
1097    default:
1098       {
1099          range_t r = {
1100             .kind  = RANGE_EXPR,
1101             .left  = expr1,
1102             .right = NULL
1103          };
1104          tree_add_range(t, r);
1105       }
1106    }
1107 
1108    tree_set_loc(t, CURRENT_LOC);
1109    return t;
1110 }
1111 
p_discrete_range(void)1112 static range_t p_discrete_range(void)
1113 {
1114    // subtype_indication | range
1115 
1116    BEGIN("discrete range");
1117 
1118    tree_t expr1 = p_expression();
1119 
1120    switch (peek()) {
1121    case tTO:
1122    case tDOWNTO:
1123    case tTICK:
1124       return p_range(expr1);
1125 
1126    case tRANGE:
1127       {
1128          if (tree_kind(expr1) != T_REF)
1129             assert(false);   // XXX: FIXME
1130 
1131          type_t type = type_new(T_UNRESOLVED);
1132          type_set_ident(type, tree_ident(expr1));
1133 
1134          consume(tRANGE);
1135          range_t r = p_range(p_expression());
1136          if (r.left != NULL)
1137              tree_set_type(r.left, type);
1138          if (r.right != NULL)
1139             tree_set_type(r.right, type);
1140 
1141          return r;
1142       }
1143 
1144    default:
1145       {
1146          range_t r = {
1147             .kind  = RANGE_EXPR,
1148             .left  = expr1,
1149             .right = NULL
1150          };
1151          return r;
1152       }
1153    }
1154 }
1155 
p_slice_name(tree_t prefix)1156 static tree_t p_slice_name(tree_t prefix)
1157 {
1158    // prefix ( discrete_range )
1159 
1160    EXTEND("slice name");
1161 
1162    tree_t t = tree_new(T_ARRAY_SLICE);
1163    tree_set_value(t, prefix);
1164 
1165    consume(tLPAREN);
1166    tree_add_range(t, p_discrete_range());
1167    consume(tRPAREN);
1168 
1169    tree_set_loc(t, CURRENT_LOC);
1170    return t;
1171 }
1172 
p_formal_part(void)1173 static tree_t p_formal_part(void)
1174 {
1175    // formal_designator
1176    //   | name ( formal_designator )
1177    //   | type_mark ( formal_designator )
1178 
1179    BEGIN("formal part");
1180 
1181    return p_name();
1182 }
1183 
p_actual_part(void)1184 static tree_t p_actual_part(void)
1185 {
1186    // actual_designator
1187    //   | name ( actual_designator )
1188    //   | type_mark ( actual_designator )
1189 
1190    BEGIN("actual part");
1191 
1192    if (optional(tOPEN)) {
1193       tree_t t = tree_new(T_OPEN);
1194       tree_set_loc(t, CURRENT_LOC);
1195       return t;
1196    }
1197 
1198    // If the actual part takes either the second or third form above then the
1199    // argument to the function call is the actual designator but only if the
1200    // call is to a named function rather than an operator
1201    // This is import for identifying conversion functions later
1202    const token_t next = peek();
1203    const bool had_name = (next == tID || next == tSTRING);
1204 
1205    tree_t designator = p_expression();
1206 
1207    const bool could_be_conversion =
1208       had_name
1209       && tree_kind(designator) == T_FCALL
1210       && tree_params(designator) == 1;
1211 
1212    if (could_be_conversion)
1213       tree_set_flag(designator, TREE_F_CONVERSION);
1214 
1215    return designator;
1216 }
1217 
p_association_element(tree_t map,add_func_t addf)1218 static void p_association_element(tree_t map, add_func_t addf)
1219 {
1220    // [ formal_part => ] actual_part
1221 
1222    BEGIN("association element");
1223 
1224    tree_t p = tree_new(T_PARAM);
1225 
1226    const look_params_t lookp = {
1227       .look     = { tASSOC },
1228       .stop     = { tCOMMA, tRPAREN },
1229       .abort    = tSEMI,
1230       .nest_in  = tLPAREN,
1231       .nest_out = tRPAREN,
1232       .depth    = 0
1233    };
1234 
1235    if (look_for(&lookp)) {
1236       tree_set_subkind(p, P_NAMED);
1237       tree_set_name(p, p_formal_part());
1238 
1239       consume(tASSOC);
1240    }
1241    else
1242       tree_set_subkind(p, P_POS);
1243 
1244    tree_set_value(p, p_actual_part());
1245    tree_set_loc(p, CURRENT_LOC);
1246 
1247    (*addf)(map, p);
1248 }
1249 
p_association_list(tree_t map,add_func_t addf)1250 static void p_association_list(tree_t map, add_func_t addf)
1251 {
1252    // association_element { , association_element }
1253 
1254    p_association_element(map, addf);
1255 
1256    while (optional(tCOMMA))
1257       p_association_element(map, addf);
1258 }
1259 
p_actual_parameter_part(tree_t call)1260 static void p_actual_parameter_part(tree_t call)
1261 {
1262    // association_list
1263 
1264    BEGIN("actual parameter part");
1265 
1266    p_association_list(call, tree_add_param);
1267 }
1268 
p_function_call(tree_t name)1269 static tree_t p_function_call(tree_t name)
1270 {
1271    // name [ ( actual_parameter_part ) ]
1272 
1273    EXTEND("function call");
1274 
1275    tree_change_kind(name, T_FCALL);
1276 
1277    consume(tLPAREN);
1278    p_actual_parameter_part(name);
1279    consume(tRPAREN);
1280 
1281    tree_set_loc(name, CURRENT_LOC);
1282    return name;
1283 }
1284 
p_attribute_name(tree_t prefix)1285 static tree_t p_attribute_name(tree_t prefix)
1286 {
1287    // prefix [ signature ] ' attribute_designator [ ( expression ) ]
1288 
1289    EXTEND("attribute name");
1290 
1291    consume(tTICK);
1292 
1293    tree_t t = tree_new(T_ATTR_REF);
1294    tree_set_name(t, prefix);
1295 
1296    if (optional(tRANGE))
1297       tree_set_ident(t, ident_new("RANGE"));
1298    else if (optional(tREVRANGE))
1299       tree_set_ident(t, ident_new("REVERSE_RANGE"));
1300    else
1301       tree_set_ident(t, p_identifier());
1302 
1303    if (optional(tLPAREN)) {
1304       add_param(t, p_expression(), P_POS, NULL);
1305       consume(tRPAREN);
1306    }
1307 
1308    tree_set_loc(t, CURRENT_LOC);
1309    return t;
1310 }
1311 
p_selected_name(tree_t prefix)1312 static tree_t p_selected_name(tree_t prefix)
1313 {
1314    // prefix . suffix
1315 
1316    EXTEND("selected name");
1317 
1318    consume(tDOT);
1319 
1320    ident_t suffix = NULL;
1321    switch (peek()) {
1322    case tID:
1323       suffix = p_identifier();
1324       break;
1325 
1326    case tSTRING:
1327       suffix = p_operator_symbol();
1328       break;
1329 
1330    case tALL:
1331       {
1332          consume(tALL);
1333 
1334          tree_t all = tree_new(T_ALL);
1335          tree_set_loc(all, CURRENT_LOC);
1336          tree_set_value(all, prefix);
1337 
1338          return all;
1339       }
1340 
1341    default:
1342       expect(tID, tALL);
1343       return prefix;
1344    }
1345 
1346    if (tree_kind(prefix) == T_REF) {
1347       ident_t joined = ident_prefix(tree_ident(prefix), suffix, '.');
1348       tree_set_ident(prefix, joined);
1349       return prefix;
1350    }
1351    else {
1352       tree_t rref = tree_new(T_RECORD_REF);
1353       tree_set_value(rref, prefix);
1354       tree_set_ident(rref, suffix);
1355       tree_set_loc(rref, CURRENT_LOC);
1356       return rref;
1357    }
1358 }
1359 
p_indexed_name(tree_t prefix)1360 static tree_t p_indexed_name(tree_t prefix)
1361 {
1362    // prefix ( expression { , expression } )
1363 
1364    EXTEND("indexed name");
1365 
1366    tree_t t = tree_new(T_ARRAY_REF);
1367    tree_set_value(t, prefix);
1368 
1369    consume(tLPAREN);
1370 
1371    do {
1372       add_param(t, p_expression(), P_POS, NULL);
1373    } while (optional(tCOMMA));
1374 
1375    consume(tRPAREN);
1376 
1377    tree_set_loc(t, CURRENT_LOC);
1378    return t;
1379 }
1380 
p_name(void)1381 static tree_t p_name(void)
1382 {
1383    // simple_name | operator_symbol | selected_name | indexed_name
1384    //   | slice_name | attribute_name
1385 
1386    BEGIN("name");
1387 
1388    ident_t id = NULL;
1389 
1390    switch (peek()) {
1391    case tSTRING:
1392       id = p_operator_symbol();
1393       break;
1394 
1395    case tID:
1396       id = p_identifier();
1397       break;
1398 
1399    default:
1400       expect(tSTRING, tID);
1401       return tree_new(T_OPEN);
1402    }
1403 
1404    tree_t name = tree_new(T_REF);
1405    tree_set_ident(name, id);
1406    tree_set_loc(name, CURRENT_LOC);
1407 
1408    for (;;) {
1409       switch (peek()) {
1410       case tLPAREN:
1411          break;
1412 
1413       case tDOT:
1414          name = p_selected_name(name);
1415          tree_set_loc(name, CURRENT_LOC);
1416          continue;
1417 
1418       case tTICK:
1419          if (peek_nth(2) == tLPAREN)
1420             return name;   // Qualified expression
1421          name = p_attribute_name(name);
1422          continue;
1423 
1424       default:
1425          return name;
1426       }
1427 
1428       // Either a function call, indexed name, or selected name
1429 
1430       const look_params_t lookp = {
1431          .look     = { tDOWNTO, tTO, tRANGE, tREVRANGE },
1432          .stop     = { tRPAREN, tCOMMA },
1433          .abort    = tSEMI,
1434          .nest_in  = tLPAREN,
1435          .nest_out = tRPAREN,
1436          .depth    = 1
1437       };
1438 
1439       if (look_for(&lookp))
1440          name = p_slice_name(name);
1441       else if (tree_kind(name) == T_REF)
1442          name = p_function_call(name);
1443       else
1444          name = p_indexed_name(name);
1445    }
1446 }
1447 
p_type_mark(void)1448 static type_t p_type_mark(void)
1449 {
1450    // name
1451 
1452    BEGIN("type mark");
1453 
1454    ident_t name = p_identifier();
1455    while (optional(tDOT))
1456       name = ident_prefix(name, p_identifier(), '.');
1457 
1458    type_t t = type_new(T_UNRESOLVED);
1459    type_set_ident(t, name);
1460    return t;
1461 }
1462 
p_index_constraint(type_t type)1463 static tree_t p_index_constraint(type_t type)
1464 {
1465    // ( discrete_range { , discrete_range } )
1466 
1467    BEGIN("index constraint");
1468 
1469    consume(tLPAREN);
1470 
1471    tree_t t = tree_new(T_CONSTRAINT);
1472    tree_set_subkind(t, C_INDEX);
1473    do {
1474       tree_add_range(t, p_discrete_range());
1475    } while (optional(tCOMMA));
1476 
1477    consume(tRPAREN);
1478 
1479    tree_set_loc(t, CURRENT_LOC);
1480    return t;
1481 }
1482 
p_constraint(type_t type)1483 static void p_constraint(type_t type)
1484 {
1485    // range_constraint | index_constraint
1486 
1487    switch (peek()) {
1488    case tRANGE:
1489       type_set_constraint(type, p_range_constraint());
1490       break;
1491 
1492    case tLPAREN:
1493       type_set_constraint(type, p_index_constraint(type));
1494       break;
1495 
1496    default:
1497       expect(tRANGE);
1498    }
1499 }
1500 
p_subtype_indication(void)1501 static type_t p_subtype_indication(void)
1502 {
1503    // [ name ] type_mark [ constraint ]
1504 
1505    BEGIN("subtype indication");
1506 
1507    bool made_subtype = false;
1508    type_t type = NULL;
1509    if ((peek() == tID) && (peek_nth(2) == tID)) {
1510       type = type_new(T_SUBTYPE);
1511       made_subtype = true;
1512 
1513       tree_t rname = p_name();
1514       // XXX: check name is resolution_function_name
1515       type_set_resolution(type, rname);
1516 
1517       type_t base = p_type_mark();
1518       type_set_base(type, base);
1519    }
1520    else
1521       type = p_type_mark();
1522 
1523    if (scan(tRANGE, tLPAREN)) {
1524       if (!made_subtype) {
1525          type_t sub = type_new(T_SUBTYPE);
1526          type_set_base(sub, type);
1527 
1528          type = sub;
1529       }
1530 
1531       p_constraint(type);
1532    }
1533 
1534    return type;
1535 }
1536 
p_abstract_literal(void)1537 static tree_t p_abstract_literal(void)
1538 {
1539    // decimal_literal | based_literal
1540 
1541    BEGIN("abstract literal");
1542 
1543    tree_t t = tree_new(T_LITERAL);
1544 
1545    switch (one_of(tINT, tREAL)) {
1546    case tINT:
1547       tree_set_subkind(t, L_INT);
1548       tree_set_ival(t, last_lval.n);
1549       break;
1550 
1551    case tREAL:
1552       tree_set_subkind(t, L_REAL);
1553       tree_set_dval(t, last_lval.d);
1554       break;
1555    }
1556 
1557    tree_set_loc(t, CURRENT_LOC);
1558    return t;
1559 }
1560 
p_physical_literal(tree_t mult)1561 static tree_t p_physical_literal(tree_t mult)
1562 {
1563    // [ abstract_literal ] name
1564 
1565    EXTEND("physical literal");
1566 
1567    tree_t unit = tree_new(T_REF);
1568    tree_set_ident(unit, p_identifier());
1569    tree_set_loc(unit, CURRENT_LOC);
1570 
1571    if (mult != NULL) {
1572       tree_t t = tree_new(T_FCALL);
1573       tree_set_loc(t, CURRENT_LOC);
1574       tree_set_ident(t, ident_new("\"*\""));
1575 
1576       add_param(t, mult, P_POS, NULL);
1577       add_param(t, unit, P_POS, NULL);
1578 
1579       return t;
1580    }
1581    else
1582       return unit;
1583 }
1584 
p_numeric_literal(void)1585 static tree_t p_numeric_literal(void)
1586 {
1587    // abstract_literal | physical_literal
1588 
1589    BEGIN("numeric literal");
1590 
1591    tree_t abs = NULL;
1592    if (scan(tINT, tREAL))
1593       abs = p_abstract_literal();
1594 
1595    if (peek() == tID)
1596       return p_physical_literal(abs);
1597    else
1598       return abs;
1599 }
1600 
p_literal(void)1601 static tree_t p_literal(void)
1602 {
1603    // numeric_literal | enumeration_literal | string_literal
1604    // | bit_string_literal | null
1605 
1606    BEGIN("literal");
1607 
1608    switch (peek()) {
1609    case tNULL:
1610       {
1611          consume(tNULL);
1612 
1613          tree_t t = tree_new(T_LITERAL);
1614          tree_set_loc(t, CURRENT_LOC);
1615          tree_set_subkind(t, L_NULL);
1616          return t;
1617       }
1618 
1619    case tINT:
1620    case tREAL:
1621       return p_numeric_literal();
1622 
1623    case tSTRING:
1624       {
1625          consume(tSTRING);
1626 
1627          char *p = last_lval.s;
1628          size_t len = strlen(p);
1629          tree_t t = str_to_literal(p + 1, p + len - 1, NULL);
1630          tree_set_loc(t, CURRENT_LOC);
1631          free(p);
1632 
1633          return t;
1634       }
1635 
1636    case tBITSTRING:
1637       {
1638          consume(tBITSTRING);
1639 
1640          tree_t t = bit_str_to_literal(last_lval.s, CURRENT_LOC);
1641          free(last_lval.s);
1642          return t;
1643       }
1644 
1645    default:
1646       expect(tNULL, tINT, tREAL);
1647       return tree_new(T_OPEN);
1648    }
1649 }
1650 
p_choice(tree_t parent)1651 static void p_choice(tree_t parent)
1652 {
1653    // simple_expression | discrete_range | simple_name | others
1654 
1655    BEGIN("choice");
1656 
1657    tree_t t = tree_new(T_ASSOC);
1658 
1659    if (optional(tOTHERS))
1660       tree_set_subkind(t, A_OTHERS);
1661    else {
1662       const look_params_t lookp = {
1663          .look     = { tDOWNTO, tTO, tRANGE, tREVRANGE },
1664          .stop     = { tRPAREN, tCOMMA, tASSOC, tBAR },
1665          .abort    = tSEMI,
1666          .nest_in  = tLPAREN,
1667          .nest_out = tRPAREN,
1668          .depth    = 0
1669       };
1670 
1671       if (look_for(&lookp)) {
1672          tree_set_subkind(t, A_RANGE);
1673          tree_add_range(t, p_discrete_range());
1674       }
1675       else {
1676          tree_set_subkind(t, A_NAMED);
1677          tree_set_name(t, p_expression());
1678       }
1679    }
1680 
1681    tree_set_loc(t, CURRENT_LOC);
1682    tree_add_assoc(parent, t);
1683 }
1684 
p_choices(tree_t parent)1685 static void p_choices(tree_t parent)
1686 {
1687    // choices ::= choice { | choice }
1688 
1689    BEGIN("choices");
1690 
1691    p_choice(parent);
1692 
1693    while (optional(tBAR))
1694       p_choice(parent);
1695 }
1696 
p_element_association(tree_t agg)1697 static void p_element_association(tree_t agg)
1698 {
1699    // [ choices => ] expression
1700 
1701    BEGIN("element association");
1702 
1703    const look_params_t lookp = {
1704       .look     = { tASSOC },
1705       .stop     = { tCOMMA, tRPAREN },
1706       .abort    = tSEMI,
1707       .nest_in  = tLPAREN,
1708       .nest_out = tRPAREN,
1709       .depth    = 0
1710    };
1711 
1712    if (look_for(&lookp)) {
1713       const int nstart = tree_assocs(agg);
1714       p_choices(agg);
1715 
1716       consume(tASSOC);
1717 
1718       tree_t value = p_expression();
1719       const int nassocs = tree_assocs(agg);
1720       for (int i = nstart; i < nassocs; i++)
1721          tree_set_value(tree_assoc(agg, i), value);
1722    }
1723    else {
1724       tree_t t = tree_new(T_ASSOC);
1725       tree_set_subkind(t, A_POS);
1726       tree_set_value(t, p_expression());
1727       tree_set_loc(t, CURRENT_LOC);
1728 
1729       tree_add_assoc(agg, t);
1730    }
1731 }
1732 
p_aggregate(void)1733 static tree_t p_aggregate(void)
1734 {
1735    // ( element_association { , element_association } )
1736 
1737    BEGIN("aggregate");
1738 
1739    tree_t t = tree_new(T_AGGREGATE);
1740 
1741    consume(tLPAREN);
1742 
1743    do {
1744       p_element_association(t);
1745    } while (optional(tCOMMA));
1746 
1747    consume(tRPAREN);
1748 
1749    tree_set_loc(t, CURRENT_LOC);
1750    return t;
1751 }
1752 
p_qualified_expression(tree_t name)1753 static tree_t p_qualified_expression(tree_t name)
1754 {
1755    // type_mark ' ( expression ) | type_mark ' aggregate
1756 
1757    EXTEND("qualified expression");
1758 
1759    tree_t t = tree_new(T_QUALIFIED);
1760 
1761    if (tree_kind(name) != T_REF)
1762       assert(false);   // XXX: FIXME
1763    else
1764       tree_set_ident(t, tree_ident(name));
1765 
1766    consume(tTICK);
1767 
1768    const look_params_t lookp = {
1769       .look     = { tCOMMA, tASSOC },
1770       .stop     = { tRPAREN },
1771       .abort    = tSEMI,
1772       .nest_in  = tLPAREN,
1773       .nest_out = tRPAREN,
1774       .depth    = 1
1775    };
1776 
1777    if (look_for(&lookp))
1778       tree_set_value(t, p_aggregate());
1779    else {
1780       consume(tLPAREN);
1781       tree_set_value(t, p_expression());
1782       consume(tRPAREN);
1783    }
1784    tree_set_loc(t, CURRENT_LOC);
1785 
1786    return t;
1787 }
1788 
p_allocator(void)1789 static tree_t p_allocator(void)
1790 {
1791    // new subtype_indication | new qualified_expression
1792 
1793    BEGIN("allocator");
1794 
1795    consume(tNEW);
1796 
1797    tree_t new = tree_new(T_NEW);
1798    tree_set_value(new, p_expression());
1799    tree_set_loc(new, CURRENT_LOC);
1800 
1801    return new;
1802 }
1803 
p_primary(void)1804 static tree_t p_primary(void)
1805 {
1806    // name | literal | aggregate | function_call | qualified_expression
1807    //   | type_conversion | allocator | ( expression )
1808 
1809    BEGIN("primary");
1810 
1811    switch (peek()) {
1812    case tLPAREN:
1813       {
1814          const look_params_t lookp = {
1815             .look     = { tCOMMA, tASSOC },
1816             .stop     = { tRPAREN },
1817             .abort    = tSEMI,
1818             .nest_in  = tLPAREN,
1819             .nest_out = tRPAREN,
1820             .depth    = 1
1821          };
1822 
1823          if (look_for(&lookp))
1824             return p_aggregate();
1825          else {
1826             consume(tLPAREN);
1827             tree_t sub = p_expression();
1828             consume(tRPAREN);
1829             return sub;
1830          }
1831       }
1832 
1833    case tINT:
1834    case tREAL:
1835    case tNULL:
1836    case tBITSTRING:
1837       return p_literal();
1838 
1839    case tSTRING:
1840       return (peek_nth(2) == tLPAREN) ? p_name() : p_literal();
1841 
1842    case tID:
1843       {
1844          tree_t name = p_name();
1845          switch (peek()) {
1846          case tTICK:
1847             return p_qualified_expression(name);
1848          default:
1849             return name;
1850          }
1851       }
1852 
1853    case tNEW:
1854       return p_allocator();
1855 
1856    default:
1857       expect(tLPAREN, tINT, tREAL, tNULL, tID, tSTRING, tBITSTRING, tNEW);
1858       return tree_new(T_OPEN);
1859    }
1860 }
1861 
p_factor(void)1862 static tree_t p_factor(void)
1863 {
1864    // primary [ ** primary ] | abs primary | not primary
1865 
1866    BEGIN("factor");
1867 
1868    ident_t op = NULL;
1869    switch (peek()) {
1870    case tNOT:
1871       consume(tNOT);
1872       op = ident_new("\"not\"");
1873       break;
1874 
1875    case tABS:
1876       consume(tABS);
1877       op = ident_new("\"abs\"");
1878       break;
1879 
1880    default:
1881       break;
1882    }
1883 
1884    tree_t operand = p_primary();
1885 
1886    if (op != NULL) {
1887       tree_t t = tree_new(T_FCALL);
1888       tree_set_loc(t, CURRENT_LOC);
1889       tree_set_ident(t, op);
1890       add_param(t, operand, P_POS, NULL);
1891 
1892       return t;
1893    }
1894    else if (optional(tPOWER)) {
1895       tree_t second = p_primary();
1896 
1897       tree_t t = tree_new(T_FCALL);
1898       tree_set_loc(t, CURRENT_LOC);
1899       tree_set_ident(t, ident_new("\"**\""));
1900       add_param(t, operand, P_POS, NULL);
1901       add_param(t, second, P_POS, NULL);
1902 
1903       return t;
1904    }
1905    else
1906       return operand;
1907 }
1908 
p_multiplying_operator(void)1909 static ident_t p_multiplying_operator(void)
1910 {
1911    switch (one_of(tTIMES, tOVER, tMOD, tREM)) {
1912    case tTIMES:
1913       return ident_new("\"*\"");
1914    case tOVER:
1915       return ident_new("\"/\"");
1916    case tMOD:
1917       return ident_new("\"mod\"");
1918    case tREM:
1919       return ident_new("\"rem\"");
1920    default:
1921       return ident_new("error");
1922    }
1923 }
1924 
p_term(void)1925 static tree_t p_term(void)
1926 {
1927    // factor { multiplying_operator factor }
1928 
1929    BEGIN("term");
1930 
1931    tree_t term = p_factor();
1932 
1933    while (scan(tTIMES, tOVER, tMOD, tREM)) {
1934       ident_t op   = p_multiplying_operator();
1935       tree_t left  = term;
1936       tree_t right = p_factor();
1937 
1938       term = tree_new(T_FCALL);
1939       tree_set_ident(term, op);
1940       tree_set_loc(term, CURRENT_LOC);
1941 
1942       add_param(term, left, P_POS, NULL);
1943       add_param(term, right, P_POS, NULL);
1944    }
1945 
1946    return term;
1947 }
1948 
p_adding_operator(void)1949 static ident_t p_adding_operator(void)
1950 {
1951    switch (one_of(tPLUS, tMINUS, tAMP)) {
1952    case tPLUS:
1953       return ident_new("\"+\"");
1954    case tMINUS:
1955       return ident_new("\"-\"");
1956    case tAMP:
1957       return ident_new("\"&\"");
1958    default:
1959       return ident_new("error");
1960    }
1961 }
1962 
p_sign(void)1963 static ident_t p_sign(void)
1964 {
1965    switch (one_of(tPLUS, tMINUS)) {
1966    case tPLUS:
1967       return ident_new("\"+\"");
1968    case tMINUS:
1969       return ident_new("\"-\"");
1970    default:
1971       return ident_new("error");
1972    }
1973 }
1974 
p_simple_expression(void)1975 static tree_t p_simple_expression(void)
1976 {
1977    // [ sign ] term { adding_operator term }
1978 
1979    BEGIN("simple expression");
1980 
1981    ident_t sign = NULL;
1982    if (scan(tPLUS, tMINUS))
1983       sign = p_sign();
1984 
1985    tree_t expr = p_term();
1986 
1987    if (sign != NULL) {
1988       tree_t tmp = tree_new(T_FCALL);
1989       tree_set_ident(tmp, sign);
1990       tree_set_loc(tmp, CURRENT_LOC);
1991 
1992       add_param(tmp, expr, P_POS, NULL);
1993 
1994       expr = tmp;
1995    }
1996 
1997    while (scan(tPLUS, tMINUS, tAMP)) {
1998       tree_t left = expr;
1999 
2000       if (optional(tAMP))
2001          expr = tree_new(T_CONCAT);
2002       else {
2003          expr = tree_new(T_FCALL);
2004          tree_set_ident(expr, p_adding_operator());
2005       }
2006 
2007       tree_t right = p_term();
2008       tree_set_loc(expr, CURRENT_LOC);
2009 
2010       add_param(expr, left, P_POS, NULL);
2011       add_param(expr, right, P_POS, NULL);
2012    }
2013 
2014    return expr;
2015 }
2016 
p_shift_operator(void)2017 static ident_t p_shift_operator(void)
2018 {
2019    switch (one_of(tSLL, tSRL, tSLA, tSRA, tROL, tROR)) {
2020    case tSLL:
2021       return ident_new("\"sll\"");
2022    case tSRL:
2023       return ident_new("\"srl\"");
2024    case tSLA:
2025       return ident_new("\"sla\"");
2026    case tSRA:
2027       return ident_new("\"sra\"");
2028    case tROL:
2029       return ident_new("\"rol\"");
2030    case tROR:
2031       return ident_new("\"ror\"");
2032    default:
2033       return ident_new("error");
2034    }
2035 }
2036 
p_shift_expression(void)2037 static tree_t p_shift_expression(void)
2038 {
2039    // simple_expression [ shift_operator simple_expression ]
2040 
2041    BEGIN("shift expression");
2042 
2043    tree_t shift = p_simple_expression();
2044 
2045    while (scan(tSLL, tSRL, tSLA, tSRA, tROL, tROR)) {
2046       ident_t op   = p_shift_operator();
2047       tree_t left  = shift;
2048       tree_t right = p_simple_expression();
2049 
2050       shift = tree_new(T_FCALL);
2051       tree_set_ident(shift, op);
2052       tree_set_loc(shift, CURRENT_LOC);
2053 
2054       add_param(shift, left, P_POS, NULL);
2055       add_param(shift, right, P_POS, NULL);
2056    }
2057 
2058    return shift;
2059 }
2060 
p_relational_operator(void)2061 static ident_t p_relational_operator(void)
2062 {
2063    switch (one_of(tEQ, tNEQ, tLT, tLE, tGT, tGE)) {
2064    case tEQ:
2065       return ident_new("\"=\"");
2066    case tNEQ:
2067       return ident_new("\"/=\"");
2068    case tLT:
2069       return ident_new("\"<\"");
2070    case tLE:
2071       return ident_new("\"<=\"");
2072    case tGT:
2073       return ident_new("\">\"");
2074    case tGE:
2075       return ident_new("\">=\"");
2076    default:
2077       return ident_new("error");
2078    }
2079 }
2080 
p_relation(void)2081 static tree_t p_relation(void)
2082 {
2083    // shift_expression [ relational_operator shift_expression ]
2084 
2085    BEGIN("relation");
2086 
2087    tree_t rel = p_shift_expression();
2088 
2089    while (scan(tEQ, tNEQ, tLT, tLE, tGT, tGE)) {
2090       ident_t op   = p_relational_operator();
2091       tree_t left  = rel;
2092       tree_t right = p_shift_expression();
2093 
2094       rel = tree_new(T_FCALL);
2095       tree_set_ident(rel, op);
2096       tree_set_loc(rel, CURRENT_LOC);
2097 
2098       add_param(rel, left, P_POS, NULL);
2099       add_param(rel, right, P_POS, NULL);
2100    }
2101 
2102    return rel;
2103 }
2104 
p_expression(void)2105 static tree_t p_expression(void)
2106 {
2107    // relation { and relation } | relation { or relation }
2108    //   | relation { xor relation } | relation [ nand relation ]
2109    //   | relation [ nor relation ] | relation { xnor relation }
2110 
2111    BEGIN("expression");
2112 
2113    tree_t expr = p_relation();
2114 
2115    int loop_limit = (scan(tNOR, tNAND) ? 1 : INT_MAX);
2116 
2117    while (loop_limit-- && scan(tAND, tOR, tXOR, tNAND, tNOR, tXNOR)) {
2118       ident_t op;
2119       switch (one_of(tAND, tOR, tXOR, tNAND, tNOR, tXNOR)) {
2120       case tAND:  op = ident_new("\"and\""); break;
2121       case tOR:   op = ident_new("\"or\""); break;
2122       case tXOR:  op = ident_new("\"xor\""); break;
2123       case tNAND: op = ident_new("\"nand\""); break;
2124       case tNOR:  op = ident_new("\"nor\""); break;
2125       case tXNOR: op = ident_new("\"xnor\""); break;
2126       default:
2127          op = ident_new("error");
2128       }
2129 
2130       tree_t left  = expr;
2131       tree_t right = p_relation();
2132 
2133       expr = tree_new(T_FCALL);
2134       tree_set_ident(expr, op);
2135       tree_set_loc(expr, CURRENT_LOC);
2136 
2137       add_param(expr, left, P_POS, NULL);
2138       add_param(expr, right, P_POS, NULL);
2139    }
2140 
2141    return expr;
2142 }
2143 
p_interface_constant_declaration(tree_t parent,add_func_t addf)2144 static void p_interface_constant_declaration(tree_t parent, add_func_t addf)
2145 {
2146    // [ constant ] identifier_list : [ in ] subtype_indication [ := expression ]
2147 
2148    BEGIN("interface constant declaration");
2149 
2150    optional(tCONSTANT);
2151 
2152    LOCAL_IDENT_LIST ids = p_identifier_list();
2153 
2154    consume(tCOLON);
2155 
2156    // The grammar only allows IN here but we are more leniant to allow the
2157    // semantic checker to generate a more helpful error message
2158    port_mode_t mode = PORT_IN;
2159    if (scan(tIN, tOUT, tINOUT, tBUFFER, tLINKAGE))
2160       mode = p_mode();
2161 
2162    type_t type = p_subtype_indication();
2163 
2164    tree_t init = NULL;
2165    if (optional(tASSIGN))
2166       init = p_expression();
2167 
2168    const loc_t *loc = CURRENT_LOC;
2169 
2170    for (ident_list_t *it = ids; it != NULL; it = it->next) {
2171       tree_t d = tree_new(T_PORT_DECL);
2172       tree_set_ident(d, it->ident);
2173       tree_set_loc(d, loc);
2174       tree_set_subkind(d, mode);
2175       tree_set_type(d, type);
2176       tree_set_class(d, C_CONSTANT);
2177 
2178       if (init != NULL)
2179          tree_set_value(d, init);
2180 
2181       (*addf)(parent, d);
2182    }
2183 }
2184 
p_interface_signal_declaration(tree_t parent,add_func_t addf)2185 static void p_interface_signal_declaration(tree_t parent, add_func_t addf)
2186 {
2187    // [signal] identifier_list : [ mode ] subtype_indication [ bus ]
2188    //    [ := expression ]
2189 
2190    BEGIN("interface signal declaration");
2191 
2192    optional(tSIGNAL);
2193    LOCAL_IDENT_LIST ids = p_identifier_list();
2194    consume(tCOLON);
2195 
2196    port_mode_t mode = PORT_IN;
2197    if (scan(tIN, tOUT, tINOUT, tBUFFER, tLINKAGE))
2198       mode = p_mode();
2199 
2200    type_t type = p_subtype_indication();
2201 
2202    optional(tBUS);
2203 
2204    tree_t init = NULL;
2205    if (optional(tASSIGN))
2206       init = p_expression();
2207 
2208    const loc_t *loc = CURRENT_LOC;
2209 
2210    for (ident_list_t *it = ids; it != NULL; it = it->next) {
2211       tree_t d = tree_new(T_PORT_DECL);
2212       tree_set_ident(d, it->ident);
2213       tree_set_loc(d, loc);
2214       tree_set_subkind(d, mode);
2215       tree_set_type(d, type);
2216       tree_set_class(d, C_SIGNAL);
2217 
2218       if (init != NULL)
2219          tree_set_value(d, init);
2220 
2221       (*addf)(parent, d);
2222    }
2223 }
2224 
p_interface_variable_declaration(tree_t parent,class_t def_class,add_func_t addf)2225 static void p_interface_variable_declaration(tree_t parent, class_t def_class, add_func_t addf)
2226 {
2227    // [variable] identifier_list : [ mode ] subtype_indication [ := expression ]
2228 
2229    BEGIN("interface variable declaration");
2230 
2231    if (optional(tVARIABLE))
2232       def_class = C_VARIABLE;
2233 
2234    LOCAL_IDENT_LIST ids = p_identifier_list();
2235    consume(tCOLON);
2236 
2237    port_mode_t mode = PORT_IN;
2238    if (scan(tIN, tOUT, tINOUT, tBUFFER, tLINKAGE))
2239       mode = p_mode();
2240 
2241    type_t type = p_subtype_indication();
2242 
2243    tree_t init = NULL;
2244    if (optional(tASSIGN))
2245       init = p_expression();
2246 
2247    const loc_t *loc = CURRENT_LOC;
2248 
2249    for (ident_list_t *it = ids; it != NULL; it = it->next) {
2250       tree_t d = tree_new(T_PORT_DECL);
2251       tree_set_ident(d, it->ident);
2252       tree_set_loc(d, loc);
2253       tree_set_subkind(d, mode);
2254       tree_set_type(d, type);
2255       tree_set_class(d, def_class);
2256 
2257       if (init != NULL)
2258          tree_set_value(d, init);
2259 
2260       (*addf)(parent, d);
2261    }
2262 }
2263 
p_interface_file_declaration(tree_t parent,add_func_t addf)2264 static void p_interface_file_declaration(tree_t parent, add_func_t addf)
2265 {
2266    // file identifier_list : subtype_indication
2267 
2268    BEGIN("interface file declaration");
2269 
2270    consume(tFILE);
2271 
2272    LOCAL_IDENT_LIST ids = p_identifier_list();
2273 
2274    consume(tCOLON);
2275 
2276    type_t type = p_subtype_indication();
2277 
2278    const loc_t *loc = CURRENT_LOC;
2279    for (ident_list_t *it = ids; it != NULL; it = it->next) {
2280       tree_t d = tree_new(T_PORT_DECL);
2281       tree_set_ident(d, it->ident);
2282       tree_set_loc(d, loc);
2283       tree_set_subkind(d, PORT_IN);
2284       tree_set_type(d, type);
2285       tree_set_class(d, C_FILE);
2286 
2287       (*addf)(parent, d);
2288    }
2289 }
2290 
p_interface_declaration(class_t def_class,tree_t parent,add_func_t addf)2291 static void p_interface_declaration(class_t def_class, tree_t parent,
2292                                     add_func_t addf)
2293 {
2294    // interface_constant_declaration | interface_signal_declaration
2295    //   | interface_variable_declaration | interface_file_declaration
2296 
2297    BEGIN("interface declaration");
2298 
2299    const token_t p = peek();
2300    switch (p) {
2301    case tCONSTANT:
2302       p_interface_constant_declaration(parent, addf);
2303       break;
2304 
2305    case tSIGNAL:
2306       p_interface_signal_declaration(parent, addf);
2307       break;
2308 
2309    case tVARIABLE:
2310       p_interface_variable_declaration(parent, C_VARIABLE, addf);
2311       break;
2312 
2313    case tFILE:
2314       p_interface_file_declaration(parent, addf);
2315       break;
2316 
2317    case tID:
2318       {
2319          switch (def_class) {
2320          case C_CONSTANT:
2321             p_interface_constant_declaration(parent, addf);
2322             break;
2323 
2324          case C_SIGNAL:
2325             p_interface_signal_declaration(parent, addf);
2326             break;
2327 
2328          case C_VARIABLE:
2329          case C_DEFAULT:
2330             p_interface_variable_declaration(parent, def_class, addf);
2331             break;
2332 
2333          default:
2334             assert(false);
2335          }
2336       }
2337       break;
2338 
2339    default:
2340       expect(tCONSTANT, tSIGNAL, tVARIABLE, tFILE, tID);
2341    }
2342 }
2343 
p_interface_element(class_t def_class,tree_t parent,add_func_t addf)2344 static void p_interface_element(class_t def_class, tree_t parent,
2345                                 add_func_t addf)
2346 {
2347    // interface_declaration
2348 
2349    BEGIN("interface element");
2350 
2351    p_interface_declaration(def_class, parent, addf);
2352 }
2353 
p_interface_list(class_t def_class,tree_t parent,add_func_t addf)2354 static void p_interface_list(class_t def_class, tree_t parent, add_func_t addf)
2355 {
2356    // interface_element { ; interface_element }
2357 
2358    BEGIN("interface list");
2359 
2360    p_interface_element(def_class, parent, addf);
2361 
2362    while (optional(tSEMI))
2363       p_interface_element(def_class, parent, addf);
2364 }
2365 
p_port_list(tree_t parent)2366 static void p_port_list(tree_t parent)
2367 {
2368    // port_list ::= interface_list
2369 
2370    BEGIN("port list");
2371 
2372    p_interface_list(C_SIGNAL, parent, tree_add_port);
2373 }
2374 
p_port_clause(tree_t parent)2375 static void p_port_clause(tree_t parent)
2376 {
2377    // port ( port_list ) ;
2378 
2379    BEGIN("port clause");
2380 
2381    consume(tPORT);
2382    consume(tLPAREN);
2383 
2384    p_port_list(parent);
2385 
2386    consume(tRPAREN);
2387    consume(tSEMI);
2388 }
2389 
p_generic_list(tree_t parent)2390 static void p_generic_list(tree_t parent)
2391 {
2392    // generic_list ::= interface_list
2393 
2394    BEGIN("generic list");
2395 
2396    p_interface_list(C_CONSTANT, parent, tree_add_generic);
2397 }
2398 
p_generic_clause(tree_t parent)2399 static void p_generic_clause(tree_t parent)
2400 {
2401    // generic ( generic_list ) ;
2402 
2403    BEGIN("generic clause");
2404 
2405    consume(tGENERIC);
2406    consume(tLPAREN);
2407 
2408    p_generic_list(parent);
2409 
2410    consume(tRPAREN);
2411    consume(tSEMI);
2412 }
2413 
p_entity_header(tree_t entity)2414 static void p_entity_header(tree_t entity)
2415 {
2416    // [ generic_clause ] [ port_clause ]
2417 
2418    BEGIN("entity header");
2419 
2420    if (scan(tGENERIC))
2421       p_generic_clause(entity);
2422 
2423    if (scan(tPORT))
2424       p_port_clause(entity);
2425 }
2426 
p_attribute_declaration(void)2427 static tree_t p_attribute_declaration(void)
2428 {
2429    // attribute identifier : type_mark ;
2430 
2431    BEGIN("attribute declaration");
2432 
2433    tree_t t = tree_new(T_ATTR_DECL);
2434 
2435    consume(tATTRIBUTE);
2436    tree_set_ident(t, p_identifier());
2437    consume(tCOLON);
2438    tree_set_type(t, p_type_mark());
2439    consume(tSEMI);
2440 
2441    tree_set_loc(t, CURRENT_LOC);
2442    return t;
2443 }
2444 
p_entity_class(void)2445 static class_t p_entity_class(void)
2446 {
2447    // entity | procedure | type | signal | label | group | architecture
2448    //   | function | subtype | variable | literal | file | configuration
2449    //   | package | constant | component | units
2450 
2451    BEGIN("entity class");
2452 
2453    switch (one_of(tENTITY, tPROCEDURE, tTYPE, tSIGNAL, tLABEL, tGROUP,
2454                   tARCHITECTURE, tFUNCTION, tSUBTYPE, tVARIABLE, tLITERAL,
2455                   tFILE, tCONFIGURATION, tPACKAGE, tCONSTANT, tCOMPONENT,
2456                   tUNITS)) {
2457    case tENTITY:
2458       return C_ENTITY;
2459    case tPROCEDURE:
2460       return C_PROCEDURE;
2461    case tTYPE:
2462       return C_TYPE;
2463    case tSIGNAL:
2464       return C_SIGNAL;
2465    case tLABEL:
2466       return C_LABEL;
2467    case tGROUP:
2468       return C_DEFAULT;
2469    case tARCHITECTURE:
2470       return C_ARCHITECTURE;
2471    case tFUNCTION:
2472       return C_FUNCTION;
2473    case tSUBTYPE:
2474       return C_SUBTYPE;
2475    case tVARIABLE:
2476       return C_VARIABLE;
2477    case tLITERAL:
2478       return C_LITERAL;
2479    case tFILE:
2480       return C_FILE;
2481    case tCONFIGURATION:
2482       return C_CONFIGURATION;
2483    case tPACKAGE:
2484       return C_PACKAGE;
2485    case tCONSTANT:
2486       return C_CONSTANT;
2487    case tCOMPONENT:
2488       return C_COMPONENT;
2489    case tUNITS:
2490       return C_UNITS;
2491    default:
2492       return C_DEFAULT;
2493    }
2494 }
2495 
p_entity_specification(class_t * class)2496 static ident_list_t *p_entity_specification(class_t *class)
2497 {
2498    // entity_name_list : entity_class
2499 
2500    BEGIN("entity specification");
2501 
2502    ident_list_t *ids = p_identifier_list();
2503 
2504    consume(tCOLON);
2505 
2506    *class = p_entity_class();
2507    return ids;
2508 }
2509 
p_attribute_specification(tree_t parent,add_func_t addf)2510 static void p_attribute_specification(tree_t parent, add_func_t addf)
2511 {
2512    // attribute attribute_designator of entity_specification is expression ;
2513 
2514    BEGIN("attribute specification");
2515 
2516    consume(tATTRIBUTE);
2517    ident_t head = p_identifier();
2518    consume(tOF);
2519 
2520    class_t class;
2521    LOCAL_IDENT_LIST ids = p_entity_specification(&class);
2522 
2523    consume(tIS);
2524 
2525    tree_t value = p_expression();
2526 
2527    consume(tSEMI);
2528 
2529    const loc_t *loc = CURRENT_LOC;
2530 
2531    for (ident_list_t *it = ids; it != NULL; it = it->next) {
2532       tree_t t = tree_new(T_ATTR_SPEC);
2533       tree_set_loc(t, loc);
2534       tree_set_class(t, class);
2535       tree_set_ident(t, head);
2536       tree_set_ident2(t, it->ident);
2537       tree_set_value(t, value);
2538 
2539       (*addf)(parent, t);
2540    }
2541 }
2542 
p_integer_type_definition(range_t r)2543 static type_t p_integer_type_definition(range_t r)
2544 {
2545    // range_constraint
2546 
2547    EXTEND("integer type definition");
2548 
2549    type_t t = type_new(T_INTEGER);
2550    type_add_dim(t, r);
2551    return t;
2552 }
2553 
p_real_type_definition(range_t r)2554 static type_t p_real_type_definition(range_t r)
2555 {
2556    // range_constraint
2557 
2558    EXTEND("real type definition");
2559 
2560    type_t t = type_new(T_REAL);
2561    type_add_dim(t, r);
2562    return t;
2563 }
2564 
p_base_unit_declaration(void)2565 static tree_t p_base_unit_declaration(void)
2566 {
2567    // identifier ;
2568 
2569    BEGIN("base unit declaration");
2570 
2571    ident_t id = p_identifier();
2572    consume(tSEMI);
2573 
2574    tree_t mult = tree_new(T_LITERAL);
2575    tree_set_loc(mult, CURRENT_LOC);
2576    tree_set_subkind(mult, L_INT);
2577    tree_set_ival(mult, 1);
2578 
2579    tree_t t = tree_new(T_UNIT_DECL);
2580    tree_set_loc(t, CURRENT_LOC);
2581    tree_set_value(t, mult);
2582    tree_set_ident(t, id);
2583 
2584    return t;
2585 }
2586 
p_secondary_unit_declaration(void)2587 static tree_t p_secondary_unit_declaration(void)
2588 {
2589    // identifier = physical_literal ;
2590 
2591    BEGIN("secondary unit declaration");
2592 
2593    ident_t id = p_identifier();
2594    consume(tEQ);
2595    tree_t value = p_physical_literal(p_abstract_literal());
2596    consume(tSEMI);
2597 
2598    tree_t u = tree_new(T_UNIT_DECL);
2599    tree_set_ident(u, id);
2600    tree_set_value(u, value);
2601    tree_set_loc(u, CURRENT_LOC);
2602 
2603    return u;
2604 }
2605 
p_physical_type_definition(range_t r)2606 static type_t p_physical_type_definition(range_t r)
2607 {
2608    // range_constraint units base_unit_declaration
2609    //   { secondary_unit_declaration } end units [ name ]
2610 
2611    EXTEND("physical type definition");
2612 
2613    type_t t = type_new(T_PHYSICAL);
2614 
2615    consume(tUNITS);
2616 
2617    tree_t base = p_base_unit_declaration();
2618    type_add_unit(t, base);
2619 
2620    r.left  = int_to_physical(r.left, base);
2621    r.right = int_to_physical(r.right, base);
2622    type_add_dim(t, r);
2623 
2624    while (scan(tINT, tREAL, tID)) {
2625       tree_t unit = p_secondary_unit_declaration();
2626       type_add_unit(t, unit);
2627    }
2628 
2629    consume(tEND);
2630    consume(tUNITS);
2631 
2632    if (peek() == tID) {
2633       ident_t id = p_identifier();
2634       (void)id;  // XXX: test this
2635    }
2636 
2637    return t;
2638 }
2639 
p_enumeration_literal(void)2640 static tree_t p_enumeration_literal(void)
2641 {
2642    // identifier | character_literal
2643 
2644    BEGIN("enumeration literal");
2645 
2646    tree_t t = tree_new(T_ENUM_LIT);
2647    tree_set_ident(t, p_identifier());
2648    tree_set_loc(t, CURRENT_LOC);
2649 
2650    return t;
2651 }
2652 
p_enumeration_type_definition(void)2653 static type_t p_enumeration_type_definition(void)
2654 {
2655    // ( enumeration_literal { , enumeration_literal } )
2656 
2657    BEGIN("enumeration type definition");
2658 
2659    type_t t = type_new(T_ENUM);
2660 
2661    consume(tLPAREN);
2662 
2663    unsigned pos = 0;
2664    do {
2665       tree_t lit = p_enumeration_literal();
2666       tree_set_pos(lit, pos++);
2667       tree_set_type(lit, t);
2668       type_enum_add_literal(t, lit);
2669    } while (optional(tCOMMA));
2670 
2671    consume(tRPAREN);
2672 
2673    return t;
2674 }
2675 
p_scalar_type_definition(void)2676 static type_t p_scalar_type_definition(void)
2677 {
2678    // enumeration_type_definition | integer_type_definition
2679    //   | floating_type_definition | physical_type_definition
2680 
2681    BEGIN("scalar type definition");
2682 
2683    switch (peek()) {
2684    case tRANGE:
2685       {
2686          range_t r = tree_range(p_range_constraint(), 0);
2687 
2688          if (peek() == tUNITS)
2689             return p_physical_type_definition(r);
2690          else {
2691             const bool real = ((r.left != NULL)
2692                                && (tree_kind(r.left) == T_LITERAL)
2693                                && (tree_subkind(r.left) == L_REAL))
2694                || ((r.right != NULL)
2695                    && (tree_kind(r.right) == T_LITERAL)
2696                    && (tree_subkind(r.right) == L_REAL));
2697 
2698             if (real)
2699                return p_real_type_definition(r);
2700             else
2701                return p_integer_type_definition(r);
2702          }
2703       }
2704 
2705    case tLPAREN:
2706       return p_enumeration_type_definition();
2707 
2708    default:
2709       expect(tRANGE);
2710       return type_new(T_NONE);
2711    }
2712 }
2713 
p_access_type_definition(void)2714 static type_t p_access_type_definition(void)
2715 {
2716    // access subtype_indication
2717 
2718    BEGIN("access type definition");
2719 
2720    consume(tACCESS);
2721 
2722    type_t t = type_new(T_ACCESS);
2723    type_set_access(t, p_subtype_indication());
2724 
2725    return t;
2726 }
2727 
p_file_type_definition(void)2728 static type_t p_file_type_definition(void)
2729 {
2730    // file of type_mark
2731 
2732    BEGIN("file type definition");
2733 
2734    consume(tFILE);
2735    consume(tOF);
2736 
2737    type_t t = type_new(T_FILE);
2738    type_set_file(t, p_type_mark());
2739 
2740    return t;
2741 }
2742 
p_element_declaration(type_t rec)2743 static void p_element_declaration(type_t rec)
2744 {
2745    // identifier_list : element_subtype_definition ;
2746 
2747    BEGIN("element declaration");
2748 
2749    LOCAL_IDENT_LIST ids = p_identifier_list();
2750 
2751    consume(tCOLON);
2752 
2753    type_t type = p_subtype_indication();
2754 
2755    consume(tSEMI);
2756 
2757    for (ident_list_t *it = ids; it != NULL; it = it->next) {
2758       tree_t f = tree_new(T_FIELD_DECL);
2759       tree_set_ident(f, it->ident);
2760       tree_set_type(f, type);
2761       tree_set_loc(f, CURRENT_LOC);
2762 
2763       type_add_field(rec, f);
2764    }
2765 }
2766 
p_record_type_definition(void)2767 static type_t p_record_type_definition(void)
2768 {
2769    // record element_declaration { element_declaration } end record
2770    //   [ simple_name ]
2771 
2772    BEGIN("record type definition");
2773 
2774    consume(tRECORD);
2775 
2776    type_t r = type_new(T_RECORD);
2777 
2778    do {
2779       p_element_declaration(r);
2780    } while (peek() == tID);
2781 
2782    consume(tEND);
2783    consume(tRECORD);
2784 
2785    if (peek() == tID) {
2786       ident_t id = p_identifier();
2787       (void)id;  // XXX: test this
2788    }
2789 
2790    return r;
2791 }
2792 
p_index_subtype_definition(void)2793 static type_t p_index_subtype_definition(void)
2794 {
2795    // type_mark range <>
2796 
2797    BEGIN("index subtype definition");
2798 
2799    type_t t = p_type_mark();
2800 
2801    consume(tRANGE);
2802    consume(tBOX);
2803 
2804    return t;
2805 }
2806 
p_unconstrained_array_definition(void)2807 static type_t p_unconstrained_array_definition(void)
2808 {
2809    // array ( index_subtype_definition { , index_subtype_definition } )
2810    //   of subtype_indication
2811 
2812    BEGIN("unconstrained array definition");
2813 
2814    consume(tARRAY);
2815    consume(tLPAREN);
2816 
2817    type_t t = type_new(T_UARRAY);
2818    do {
2819       type_add_index_constr(t, p_index_subtype_definition());
2820    } while (optional(tCOMMA));
2821 
2822    consume(tRPAREN);
2823    consume(tOF);
2824 
2825    type_set_elem(t, p_subtype_indication());
2826    return t;
2827 }
2828 
p_constrained_array_definition(void)2829 static type_t p_constrained_array_definition(void)
2830 {
2831    // array index_constraint of element_subtype_indication
2832 
2833    BEGIN("constrained array definition");
2834 
2835    consume(tARRAY);
2836 
2837    type_t t = type_new(T_CARRAY);
2838    tree_t tmp = p_index_constraint(t);  // XXXX
2839    for (int i = 0; i < tree_ranges(tmp); i++)
2840       type_add_dim(t, tree_range(tmp, i));
2841 
2842    consume(tOF);
2843 
2844    type_set_elem(t, p_subtype_indication());
2845    return t;
2846 }
2847 
p_array_type_definition(void)2848 static type_t p_array_type_definition(void)
2849 {
2850    // unconstrained_array_definition | constrained_array_definition
2851 
2852    BEGIN("array type definition");
2853 
2854    const look_params_t lookp = {
2855       .look     = { tBOX },
2856       .stop     = { tRPAREN },
2857       .abort    = tSEMI,
2858       .nest_in  = tLPAREN,
2859       .nest_out = tRPAREN,
2860       .depth    = 1
2861    };
2862 
2863    if (look_for(&lookp))
2864       return p_unconstrained_array_definition();
2865    else
2866       return p_constrained_array_definition();
2867 }
2868 
p_composite_type_definition(void)2869 static type_t p_composite_type_definition(void)
2870 {
2871    // array_type_definition | record_type_definition
2872 
2873    BEGIN("composite type definition");
2874 
2875    switch (peek()) {
2876    case tRECORD:
2877       return p_record_type_definition();
2878 
2879    case tARRAY:
2880       return p_array_type_definition();
2881 
2882    default:
2883       expect(tRECORD, tARRAY);
2884       return type_new(T_NONE);
2885    }
2886 }
2887 
p_protected_type_declarative_item(type_t type)2888 static void p_protected_type_declarative_item(type_t type)
2889 {
2890    // subprogram_declaration | 2008: subprogram_instantiation_declaration
2891    //   | attribute_specification | use_clause
2892 
2893    BEGIN("protected type declarative item");
2894 
2895    switch (peek()) {
2896    case tATTRIBUTE:
2897       p_attribute_specification((tree_t)type, (add_func_t)type_add_unit);
2898       break;
2899 
2900    case tUSE:
2901       p_use_clause((tree_t)type, (add_func_t)type_add_unit);
2902       break;
2903 
2904    case tFUNCTION:
2905    case tPROCEDURE:
2906    case tIMPURE:
2907    case tPURE:
2908       {
2909          tree_t spec = p_subprogram_specification();
2910          type_add_decl(type, p_subprogram_declaration(spec));
2911       }
2912       break;
2913 
2914    default:
2915       expect(tATTRIBUTE, tUSE, tFUNCTION, tPROCEDURE, tIMPURE, tPURE);
2916    }
2917 }
2918 
p_protected_type_declarative_part(type_t type)2919 static void p_protected_type_declarative_part(type_t type)
2920 {
2921    // { protected_type_declarative_item }
2922 
2923    BEGIN("protected type declarative part");
2924 
2925    while (not_at_token(tEND))
2926       p_protected_type_declarative_item(type);
2927 }
2928 
p_protected_type_declaration(void)2929 static type_t p_protected_type_declaration(void)
2930 {
2931    // protected protected_type_declarative_part end protected [ simple_name ]
2932 
2933    BEGIN("protected type declaration");
2934 
2935    consume(tPROTECTED);
2936 
2937    type_t type = type_new(T_PROTECTED);
2938 
2939    p_protected_type_declarative_part(type);
2940 
2941    consume(tEND);
2942    consume(tPROTECTED);
2943 
2944    if (peek() == tID)
2945       type_set_ident(type, p_identifier());
2946 
2947    return type;
2948 }
2949 
p_protected_type_definition(void)2950 static type_t p_protected_type_definition(void)
2951 {
2952    // protected_type_declaration | protected_type_body
2953 
2954    BEGIN("protected type definition");
2955 
2956    // Protected type bodies are trees rather than types and so handled
2957    // elsewhere to simplify the parser
2958 
2959    return p_protected_type_declaration();
2960 }
2961 
p_type_definition(void)2962 static type_t p_type_definition(void)
2963 {
2964    // scalar_type_definition | composite_type_definition
2965    //   | access_type_definition | file_type_definition
2966    //   | 2000: protected_type_definition
2967 
2968    BEGIN("type definition");
2969 
2970    switch (peek()) {
2971    case tRANGE:
2972    case tLPAREN:
2973       return p_scalar_type_definition();
2974 
2975    case tACCESS:
2976       return p_access_type_definition();
2977 
2978    case tFILE:
2979       return p_file_type_definition();
2980 
2981    case tRECORD:
2982    case tARRAY:
2983       return p_composite_type_definition();
2984 
2985    case tPROTECTED:
2986       return p_protected_type_definition();
2987 
2988    default:
2989       expect(tRANGE, tACCESS, tFILE, tRECORD, STD(00, tPROTECTED));
2990       return type_new(T_NONE);
2991    }
2992 }
2993 
p_full_type_declaration(ident_t id)2994 static type_t p_full_type_declaration(ident_t id)
2995 {
2996    // type identifier is type_definition ;
2997 
2998    EXTEND("full type declaration");
2999 
3000    consume(tIS);
3001 
3002    type_t t = p_type_definition();
3003    type_set_ident(t, id);
3004 
3005    consume(tSEMI);
3006 
3007    return t;
3008 }
3009 
p_incomplete_type_declaration(ident_t id)3010 static type_t p_incomplete_type_declaration(ident_t id)
3011 {
3012    // type identifier ;
3013 
3014    EXTEND("incomplete type declaration");
3015 
3016    consume(tSEMI);
3017 
3018    type_t t = type_new(T_INCOMPLETE);
3019    type_set_ident(t, id);
3020 
3021    return t;
3022 }
3023 
p_type_declaration(void)3024 static tree_t p_type_declaration(void)
3025 {
3026    // full_type_declaration | incomplete_type_declaration
3027 
3028    BEGIN("type declaration");
3029 
3030    consume(tTYPE);
3031 
3032    ident_t id = p_identifier();
3033 
3034    // Protected type bodies are broken out here to avoid having to
3035    // return a dummy type for them in p_full_type_declaration
3036 
3037    const bool is_prot_body =
3038       (peek_nth(1) == tIS)
3039       && (peek_nth(2) == tPROTECTED)
3040       && (peek_nth(3) == tBODY);
3041 
3042    if (is_prot_body) {
3043       consume(tIS);
3044       tree_t body = p_protected_type_body();
3045       consume(tSEMI);
3046 
3047       if (tree_has_ident(body)) {
3048          if (tree_ident(body) != id)
3049             parse_error(CURRENT_LOC, "expected protected body trailing label "
3050                         "to match %s", istr(id));
3051       }
3052       else
3053          tree_set_ident(body, id);
3054 
3055       return body;
3056    }
3057    else {
3058       type_t type;
3059       if (peek() == tSEMI)
3060          type = p_incomplete_type_declaration(id);
3061       else
3062          type = p_full_type_declaration(id);
3063 
3064       type_set_ident(type, id);
3065 
3066       tree_t t = tree_new(T_TYPE_DECL);
3067       tree_set_ident(t, id);
3068       tree_set_type(t, type);
3069       tree_set_loc(t, CURRENT_LOC);
3070 
3071       return t;
3072    }
3073 }
3074 
p_subtype_declaration(void)3075 static tree_t p_subtype_declaration(void)
3076 {
3077    // subtype identifier is subtype_indication ;
3078 
3079    BEGIN("subtype declaration");
3080 
3081    consume(tSUBTYPE);
3082    ident_t id = p_identifier();
3083    consume(tIS);
3084    type_t sub = p_subtype_indication();
3085    consume(tSEMI);
3086 
3087    if (type_kind(sub) != T_SUBTYPE) {
3088       // Case where subtype_indication did not impose any
3089       // constraint so we must create the subtype object here
3090       type_t new = type_new(T_SUBTYPE);
3091       type_set_base(new, sub);
3092 
3093       sub = new;
3094    }
3095    type_set_ident(sub, id);
3096 
3097    tree_t t = tree_new(T_TYPE_DECL);
3098    tree_set_ident(t, id);
3099    tree_set_type(t, sub);
3100    tree_set_loc(t, CURRENT_LOC);
3101 
3102    return t;
3103 }
3104 
p_constant_declaration(tree_t parent)3105 static void p_constant_declaration(tree_t parent)
3106 {
3107    // constant identifier_list : subtype_indication [ := expression ] ;
3108 
3109    BEGIN("constant declaration");
3110 
3111    consume(tCONSTANT);
3112 
3113    LOCAL_IDENT_LIST ids = p_identifier_list();
3114 
3115    consume(tCOLON);
3116 
3117    type_t type = p_subtype_indication();
3118 
3119    tree_t init = NULL;
3120    if (optional(tASSIGN))
3121       init = p_expression();
3122 
3123    consume(tSEMI);
3124 
3125    for (ident_list_t *it = ids; it != NULL; it = it->next) {
3126       tree_t t = tree_new(T_CONST_DECL);
3127       tree_set_ident(t, it->ident);
3128       tree_set_type(t, type);
3129       tree_set_loc(t, CURRENT_LOC);
3130       if (init != NULL)
3131          tree_set_value(t, init);
3132 
3133       tree_add_decl(parent, t);
3134    }
3135 }
3136 
p_assertion(void)3137 static tree_t p_assertion(void)
3138 {
3139    // assert condition [ report expression ] [ severity expression ]
3140 
3141    BEGIN("assertion");
3142 
3143    tree_t s = tree_new(T_ASSERT);
3144 
3145    consume(tASSERT);
3146 
3147    tree_set_value(s, p_expression());
3148 
3149    if (optional(tREPORT))
3150       tree_set_message(s, p_expression());
3151 
3152    if (optional(tSEVERITY))
3153       tree_set_severity(s, p_expression());
3154    else {
3155       tree_t sev = tree_new(T_REF);
3156       tree_set_ident(sev, ident_new("ERROR"));
3157 
3158       tree_set_severity(s, sev);
3159    }
3160 
3161    tree_set_loc(s, CURRENT_LOC);
3162    return s;
3163 }
3164 
p_concurrent_assertion_statement(ident_t label)3165 static tree_t p_concurrent_assertion_statement(ident_t label)
3166 {
3167    // [ label : ] [ postponed ] assertion ;
3168 
3169    BEGIN("concurrent assertion statement");
3170 
3171    const bool postponed = optional(tPOSTPONED);
3172 
3173    tree_t s = p_assertion();
3174    tree_change_kind(s, T_CASSERT);
3175 
3176    consume(tSEMI);
3177 
3178    const loc_t *loc = CURRENT_LOC;
3179    tree_set_loc(s, loc);
3180 
3181    if (label == NULL)
3182       label = loc_to_ident(loc);
3183    tree_set_ident(s, label);
3184 
3185    if (postponed)
3186       tree_set_flag(s, TREE_F_POSTPONED);
3187 
3188    return s;
3189 }
3190 
p_designator(void)3191 static ident_t p_designator(void)
3192 {
3193    // identifier | operator_symbol
3194 
3195    BEGIN("designator");
3196 
3197    switch (peek()) {
3198    case tID:
3199       return p_identifier();
3200    case tSTRING:
3201       return p_operator_symbol();
3202    default:
3203       expect(tID, tSTRING);
3204       return ident_new("error");
3205    }
3206 }
3207 
p_subprogram_specification(void)3208 static tree_t p_subprogram_specification(void)
3209 {
3210    // procedure designator [ ( formal_parameter_list ) ]
3211    //   | [ pure | impure ] function designator [ ( formal_parameter_list ) ]
3212    //     return type_mark
3213 
3214    BEGIN("subprogram specification");
3215 
3216    tree_t t = NULL;
3217    type_t type = NULL;
3218 
3219    bool impure = false;
3220    if (optional(tIMPURE))
3221       impure = true;
3222    else if (optional(tPURE))
3223       ;
3224 
3225    switch (one_of(tFUNCTION, tPROCEDURE)) {
3226    case tFUNCTION:
3227       t = tree_new(T_FUNC_DECL);
3228       type = type_new(T_FUNC);
3229       break;
3230 
3231    case tPROCEDURE:
3232       t = tree_new(T_PROC_DECL);
3233       type = type_new(T_PROC);
3234       break;
3235 
3236    default:
3237       return tree_new(T_FUNC_DECL);
3238    }
3239 
3240    tree_set_type(t, type);
3241    tree_set_ident(t, p_designator());
3242 
3243    type_set_ident(type, tree_ident(t));
3244 
3245    if (impure)
3246       tree_set_flag(t, TREE_F_IMPURE);
3247 
3248    if (optional(tLPAREN)) {
3249       //const class_t class =
3250       //   (tree_kind(t) == T_FUNC_DECL) ? C_CONSTANT : C_VARIABLE;
3251       p_interface_list(C_DEFAULT, t, tree_add_port);
3252       consume(tRPAREN);
3253    }
3254 
3255    if (tree_kind(t) == T_FUNC_DECL) {
3256       consume(tRETURN);
3257       type_set_result(type, p_type_mark());
3258    }
3259 
3260    tree_set_loc(t, CURRENT_LOC);
3261    return t;
3262 }
3263 
p_variable_declaration(tree_t parent)3264 static void p_variable_declaration(tree_t parent)
3265 {
3266    // [ shared ] variable identifier_list : subtype_indication
3267    //   [ := expression ] ;
3268 
3269    BEGIN("variable declaration");
3270 
3271    const bool shared = optional(tSHARED);
3272 
3273    consume(tVARIABLE);
3274 
3275    LOCAL_IDENT_LIST ids = p_identifier_list();
3276 
3277    consume(tCOLON);
3278 
3279    type_t type = p_subtype_indication();
3280 
3281    tree_t init = NULL;
3282    if (optional(tASSIGN))
3283       init = p_expression();
3284 
3285    consume(tSEMI);
3286 
3287    const loc_t *loc = CURRENT_LOC;
3288 
3289    for (ident_list_t *it = ids; it != NULL; it = it->next) {
3290       tree_t t = tree_new(T_VAR_DECL);
3291       tree_set_loc(t, loc);
3292       tree_set_ident(t, it->ident);
3293       tree_set_type(t, type);
3294 
3295       if (init != NULL)
3296          tree_set_value(t, init);
3297 
3298       if (shared)
3299          tree_set_flag(t, TREE_F_SHARED);
3300 
3301       tree_add_decl(parent, t);
3302    }
3303 }
3304 
p_signal_declaration(tree_t parent)3305 static void p_signal_declaration(tree_t parent)
3306 {
3307    // signal identifier_list : subtype_indication [ signal_kind ]
3308    //   [ := expression ] ;
3309 
3310    BEGIN("signal declaration");
3311 
3312    consume(tSIGNAL);
3313 
3314    LOCAL_IDENT_LIST ids = p_identifier_list();
3315 
3316    consume(tCOLON);
3317 
3318    type_t type = p_subtype_indication();
3319 
3320    // [ signal_kind ]
3321 
3322    tree_t init = NULL;
3323    if (optional(tASSIGN))
3324       init = p_expression();
3325 
3326    consume(tSEMI);
3327 
3328    const loc_t *loc = CURRENT_LOC;
3329 
3330    for (ident_list_t *it = ids; it != NULL; it = it->next) {
3331       tree_t t = tree_new(T_SIGNAL_DECL);
3332       tree_set_loc(t, loc);
3333       tree_set_ident(t, it->ident);
3334       tree_set_type(t, type);
3335 
3336       if (init != NULL)
3337          tree_set_value(t, init);
3338 
3339       tree_add_decl(parent, t);
3340    }
3341 }
3342 
p_signature(void)3343 static type_t p_signature(void)
3344 {
3345    // [ [ type_mark { , type_mark } ] [ return type_mark ] ]
3346 
3347    BEGIN("signature");
3348 
3349    const look_params_t lookp = {
3350       .look   = { tRETURN },
3351       .stop   = { tRSQUARE },
3352       .abort  = tSEMI
3353    };
3354 
3355    type_t type = type_new(look_for(&lookp) ? T_FUNC : T_PROC);
3356 
3357    consume(tLSQUARE);
3358 
3359    if (not_at_token(tRETURN, tRSQUARE)) {
3360       type_add_param(type, p_type_mark());
3361       while (optional(tCOMMA))
3362          type_add_param(type, p_type_mark());
3363    }
3364 
3365    if (optional(tRETURN))
3366       type_set_result(type, p_type_mark());
3367 
3368    consume(tRSQUARE);
3369 
3370    return type;
3371 }
3372 
p_alias_declaration(void)3373 static tree_t p_alias_declaration(void)
3374 {
3375    // alias alias_designator [ : subtype_indication ] is name [ signature ] ;
3376 
3377    BEGIN("alias declaration");
3378 
3379    tree_t t = tree_new(T_ALIAS);
3380 
3381    bool has_subtype_indication = false;
3382    consume(tALIAS);
3383    tree_set_ident(t, p_identifier());
3384    if (optional(tCOLON)) {
3385       tree_set_type(t, p_subtype_indication());
3386       has_subtype_indication = true;
3387    }
3388    consume(tIS);
3389    tree_set_value(t, p_name());
3390 
3391    if (peek() == tLSQUARE) {
3392       tree_set_type(t, p_signature());
3393       if (has_subtype_indication)
3394          parse_error(CURRENT_LOC, "alias declaration may not contain both a "
3395                      "signature and a subtype indication");
3396    }
3397 
3398    consume(tSEMI);
3399 
3400    tree_set_loc(t, CURRENT_LOC);
3401    return t;
3402 }
3403 
p_file_open_information(tree_t * mode,tree_t * name)3404 static void p_file_open_information(tree_t *mode, tree_t *name)
3405 {
3406    // [ open expression ] is file_logical_name
3407 
3408    BEGIN("file open information");
3409 
3410    if (optional(tOPEN))
3411       *mode = p_expression();
3412    else
3413       *mode = NULL;
3414 
3415    if (optional(tIS)) {
3416       if ((*mode == NULL) && scan(tIN, tOUT)) {
3417          // VHDL-87 compatibility
3418          switch (one_of(tIN, tOUT)) {
3419          case tIN:
3420             *mode = tree_new(T_REF);
3421             tree_set_ident(*mode, ident_new("READ_MODE"));
3422             break;
3423 
3424          case tOUT:
3425             *mode = tree_new(T_REF);
3426             tree_set_ident(*mode, ident_new("WRITE_MODE"));
3427             break;
3428          }
3429       }
3430 
3431       *name = p_expression();
3432 
3433       if (*mode == NULL) {
3434          *mode = tree_new(T_REF);
3435          tree_set_ident(*mode, ident_new("READ_MODE"));
3436       }
3437    }
3438    else
3439       *name = NULL;
3440 }
3441 
p_file_declaration(tree_t parent)3442 static void p_file_declaration(tree_t parent)
3443 {
3444    // file identifier_list : subtype_indication [ file_open_information ] ;
3445 
3446    BEGIN("file declaration");
3447 
3448    consume(tFILE);
3449 
3450    LOCAL_IDENT_LIST ids = p_identifier_list();
3451 
3452    consume(tCOLON);
3453 
3454    type_t type = p_subtype_indication();
3455 
3456    tree_t mode, name;
3457    p_file_open_information(&mode, &name);
3458 
3459    consume(tSEMI);
3460 
3461    for (ident_list_t *it = ids; it != NULL; it = it->next) {
3462       tree_t t = tree_new(T_FILE_DECL);
3463       tree_set_ident(t, it->ident);
3464       tree_set_type(t, type);
3465       if (name != NULL) {
3466          tree_set_file_mode(t, mode);
3467          tree_set_value(t, name);
3468       }
3469       tree_set_loc(t, CURRENT_LOC);
3470 
3471       tree_add_decl(parent, t);
3472    }
3473 }
3474 
p_protected_type_body_declarative_item(tree_t body)3475 static void p_protected_type_body_declarative_item(tree_t body)
3476 {
3477    // subprogram_declaration | subprogram_body | type_declaration
3478    //   | subtype_declaration | constant_declaration | variable_declaration
3479    //   | file_declaration | alias_declaration | attribute_declaration
3480    //   | attribute_specification | use_clause | group_template_declaration
3481    //   | group_declaration
3482 
3483    BEGIN("protected type body declarative item");
3484 
3485    switch (peek()) {
3486    case tATTRIBUTE:
3487       if (peek_nth(3) == tOF)
3488          p_attribute_specification(body, tree_add_decl);
3489       else
3490          tree_add_decl(body, p_attribute_declaration());
3491       break;
3492 
3493    case tTYPE:
3494       tree_add_decl(body, p_type_declaration());
3495       break;
3496 
3497    case tSUBTYPE:
3498       tree_add_decl(body, p_subtype_declaration());
3499       break;
3500 
3501    case tCONSTANT:
3502       p_constant_declaration(body);
3503       break;
3504 
3505    case tALIAS:
3506       tree_add_decl(body, p_alias_declaration());
3507       break;
3508 
3509    case tFUNCTION:
3510    case tPROCEDURE:
3511    case tIMPURE:
3512    case tPURE:
3513       {
3514          tree_t spec = p_subprogram_specification();
3515          if (peek() == tSEMI)
3516             tree_add_decl(body, p_subprogram_declaration(spec));
3517          else
3518             tree_add_decl(body, p_subprogram_body(spec));
3519       }
3520       break;
3521 
3522    case tVARIABLE:
3523       p_variable_declaration(body);
3524       break;
3525 
3526    case tUSE:
3527       p_use_clause(body, tree_add_decl);
3528       break;
3529 
3530    case tFILE:
3531       p_file_declaration(body);
3532       break;
3533 
3534    default:
3535       expect(tATTRIBUTE, tTYPE, tSUBTYPE, tCONSTANT, tFUNCTION, tPROCEDURE,
3536              tIMPURE, tPURE, tALIAS, tVARIABLE, tUSE, tFILE);
3537    }
3538 }
3539 
p_protected_type_body_declarative_part(tree_t body)3540 static void p_protected_type_body_declarative_part(tree_t body)
3541 {
3542    // { protected_type_body_declarative_item }
3543 
3544    BEGIN("protected type body declarative part");
3545 
3546    while (not_at_token(tEND))
3547       p_protected_type_body_declarative_item(body);
3548 }
3549 
p_protected_type_body(void)3550 static tree_t p_protected_type_body(void)
3551 {
3552    // protected body protected_type_body_declarative_part end protected body
3553    //   [ simple name ]
3554 
3555    BEGIN("protected type body");
3556 
3557    consume(tPROTECTED);
3558    consume(tBODY);
3559 
3560    tree_t body = tree_new(T_PROT_BODY);
3561    p_protected_type_body_declarative_part(body);
3562 
3563    consume(tEND);
3564    consume(tPROTECTED);
3565    consume(tBODY);
3566 
3567    if (peek() == tID)
3568       tree_set_ident(body, p_identifier());
3569 
3570    tree_set_loc(body, CURRENT_LOC);
3571    return body;
3572 }
3573 
p_entity_declarative_item(tree_t entity)3574 static void p_entity_declarative_item(tree_t entity)
3575 {
3576    // subprogram_declaration | subprogram_body | type_declaration
3577    //   | subtype_declaration | constant_declaration | signal_declaration
3578    //   | shared_variable_declaration | file_declaration | alias_declaration
3579    //   | attribute_declaration | attribute_specification
3580    //   | disconnection_specification | use_clause | group_template_declaration
3581    //   | group_declaration
3582 
3583    BEGIN("entity declarative item");
3584 
3585    switch (peek()) {
3586    case tATTRIBUTE:
3587       if (peek_nth(3) == tOF)
3588          p_attribute_specification(entity, tree_add_decl);
3589       else
3590          tree_add_decl(entity, p_attribute_declaration());
3591       break;
3592 
3593    case tTYPE:
3594       tree_add_decl(entity, p_type_declaration());
3595       break;
3596 
3597    case tSUBTYPE:
3598       tree_add_decl(entity, p_subtype_declaration());
3599       break;
3600 
3601    case tCONSTANT:
3602       p_constant_declaration(entity);
3603       break;
3604 
3605    case tALIAS:
3606       tree_add_decl(entity, p_alias_declaration());
3607       break;
3608 
3609    case tFUNCTION:
3610    case tPROCEDURE:
3611    case tIMPURE:
3612    case tPURE:
3613       {
3614          tree_t spec = p_subprogram_specification();
3615          if (peek() == tSEMI)
3616             tree_add_decl(entity, p_subprogram_declaration(spec));
3617          else
3618             tree_add_decl(entity, p_subprogram_body(spec));
3619       }
3620       break;
3621 
3622    case tUSE:
3623       p_use_clause(entity, tree_add_decl);
3624       break;
3625 
3626    default:
3627       expect(tATTRIBUTE, tTYPE, tSUBTYPE, tCONSTANT, tFUNCTION, tPROCEDURE,
3628              tIMPURE, tPURE, tALIAS, tUSE);
3629    }
3630 }
3631 
p_entity_declarative_part(tree_t entity)3632 static void p_entity_declarative_part(tree_t entity)
3633 {
3634    // { entity_declarative_item }
3635 
3636    BEGIN("entity declarative part");
3637 
3638    while (not_at_token(tEND, tBEGIN))
3639       p_entity_declarative_item(entity);
3640 }
3641 
p_subprogram_declarative_item(tree_t sub)3642 static void p_subprogram_declarative_item(tree_t sub)
3643 {
3644    // subprogram_declaration | subprogram_body | type_declaration
3645    //   | subtype_declaration | constant_declaration | variable_declaration
3646    //   | file_declaration | alias_declaration | attribute_declaration
3647    //   | attribute_specification | use_clause | group_template_declaration
3648    //   | group_declaration
3649 
3650    BEGIN("subprogram delcarative item");
3651 
3652    switch (peek()) {
3653    case tVARIABLE:
3654       p_variable_declaration(sub);
3655       break;
3656 
3657    case tTYPE:
3658       tree_add_decl(sub, p_type_declaration());
3659       break;
3660 
3661    case tALIAS:
3662       tree_add_decl(sub, p_alias_declaration());
3663       break;
3664 
3665    case tCONSTANT:
3666       p_constant_declaration(sub);
3667       break;
3668 
3669    case tFUNCTION:
3670    case tPROCEDURE:
3671    case tIMPURE:
3672    case tPURE:
3673       {
3674          tree_t spec = p_subprogram_specification();
3675          if (peek() == tSEMI)
3676             tree_add_decl(sub, p_subprogram_declaration(spec));
3677          else
3678             tree_add_decl(sub, p_subprogram_body(spec));
3679       }
3680       break;
3681 
3682    case tATTRIBUTE:
3683       if (peek_nth(3) == tOF)
3684          p_attribute_specification(sub, tree_add_decl);
3685       else
3686          tree_add_decl(sub, p_attribute_declaration());
3687       break;
3688 
3689    case tSUBTYPE:
3690       tree_add_decl(sub, p_subtype_declaration());
3691       break;
3692 
3693    case tUSE:
3694       p_use_clause(sub, tree_add_decl);
3695       break;
3696 
3697    case tFILE:
3698       p_file_declaration(sub);
3699       break;
3700 
3701    default:
3702       expect(tVARIABLE, tTYPE, tALIAS, tCONSTANT, tFUNCTION, tPROCEDURE,
3703              tIMPURE, tPURE, tATTRIBUTE, tSUBTYPE, tUSE, tFILE);
3704    }
3705 }
3706 
p_subprogram_declarative_part(tree_t sub)3707 static void p_subprogram_declarative_part(tree_t sub)
3708 {
3709    // { subprogram_declarative_item }
3710 
3711    BEGIN("subprogram declarative part");
3712 
3713    while (not_at_token(tBEGIN))
3714       p_subprogram_declarative_item(sub);
3715 }
3716 
p_sequence_of_statements(tree_t parent,add_func_t addf)3717 static void p_sequence_of_statements(tree_t parent, add_func_t addf)
3718 {
3719    // { sequential_statement }
3720 
3721    BEGIN("sequence of statements");
3722 
3723    while (not_at_token(tEND, tELSE, tELSIF, tWHEN))
3724       (*addf)(parent, p_sequential_statement());
3725 }
3726 
p_trailing_label(ident_t label)3727 static void p_trailing_label(ident_t label)
3728 {
3729    // [ label ]
3730 
3731    if ((peek() == tID) || (peek() == tSTRING)) {
3732       ident_t trailing = p_designator();
3733       if (label == NULL)
3734          parse_error(&last_loc, "unexpected trailing label for %s without "
3735                      "label", hint_str);
3736       else if (trailing != label)
3737          parse_error(&last_loc, "expected trailing %s label to match %s",
3738                      hint_str, istr(label));
3739    }
3740 }
3741 
p_subprogram_body(tree_t spec)3742 static tree_t p_subprogram_body(tree_t spec)
3743 {
3744    // subprogram_specification is subprogram_declarative_part begin
3745    //   subprogram_statement_part end [ subprogram_kind ] [ designator ] ;
3746 
3747    EXTEND("subprogram body");
3748 
3749    consume(tIS);
3750 
3751    const tree_kind_t kind =
3752       (tree_kind(spec) == T_FUNC_DECL) ? T_FUNC_BODY : T_PROC_BODY;
3753    tree_change_kind(spec, kind);
3754 
3755    p_subprogram_declarative_part(spec);
3756 
3757    consume(tBEGIN);
3758 
3759    p_sequence_of_statements(spec, tree_add_stmt);
3760 
3761    consume(tEND);
3762 
3763    switch (peek()) {
3764    case tFUNCTION:
3765       consume(tFUNCTION);
3766       // XXX: check is function;
3767       break;
3768 
3769    case tPROCEDURE:
3770       consume(tPROCEDURE);
3771       // XXX: check is procedure
3772       break;
3773 
3774    default:
3775       break;
3776    }
3777 
3778    p_trailing_label(tree_ident(spec));
3779    consume(tSEMI);
3780 
3781    tree_set_loc(spec, CURRENT_LOC);
3782    return spec;
3783 }
3784 
p_subprogram_declaration(tree_t spec)3785 static tree_t p_subprogram_declaration(tree_t spec)
3786 {
3787    // subprogram_specification ;
3788 
3789    EXTEND("subprogram declaration");
3790 
3791    consume(tSEMI);
3792    return spec;
3793 }
3794 
p_sensitivity_list(tree_t proc)3795 static void p_sensitivity_list(tree_t proc)
3796 {
3797    // name { , name }
3798 
3799    BEGIN("sensitivity list");
3800 
3801    tree_add_trigger(proc, p_name());
3802 
3803    while (optional(tCOMMA))
3804       tree_add_trigger(proc, p_name());
3805 }
3806 
p_process_declarative_item(tree_t proc)3807 static void p_process_declarative_item(tree_t proc)
3808 {
3809    // subprogram_declaration | subprogram_body | type_declaration
3810    //   | subtype_declaration | constant_declaration | variable_declaration
3811    //   | file_declaration | alias_declaration | attribute_declaration
3812    //   | attribute_specification | use_clause | group_template_declaration
3813    //   | group_declaration
3814 
3815    BEGIN("process declarative item");
3816 
3817    switch (peek()) {
3818    case tVARIABLE:
3819       p_variable_declaration(proc);
3820       break;
3821 
3822    case tTYPE:
3823       tree_add_decl(proc, p_type_declaration());
3824       break;
3825 
3826    case tSUBTYPE:
3827       tree_add_decl(proc, p_subtype_declaration());
3828       break;
3829 
3830    case tCONSTANT:
3831       p_constant_declaration(proc);
3832       break;
3833 
3834    case tFUNCTION:
3835    case tPROCEDURE:
3836    case tIMPURE:
3837    case tPURE:
3838       {
3839          tree_t spec = p_subprogram_specification();
3840          if (peek() == tSEMI)
3841             tree_add_decl(proc, p_subprogram_declaration(spec));
3842          else
3843             tree_add_decl(proc, p_subprogram_body(spec));
3844       }
3845       break;
3846 
3847    case tATTRIBUTE:
3848       if (peek_nth(3) == tOF)
3849          p_attribute_specification(proc, tree_add_decl);
3850       else
3851          tree_add_decl(proc, p_attribute_declaration());
3852       break;
3853 
3854    case tUSE:
3855       p_use_clause(proc, tree_add_decl);
3856       break;
3857 
3858    case tALIAS:
3859       tree_add_decl(proc, p_alias_declaration());
3860       break;
3861 
3862    case tFILE:
3863       p_file_declaration(proc);
3864       break;
3865 
3866    default:
3867       expect(tVARIABLE, tTYPE, tSUBTYPE, tCONSTANT, tFUNCTION, tPROCEDURE,
3868              tIMPURE, tPURE, tATTRIBUTE, tUSE, tALIAS, tFILE);
3869    }
3870 }
3871 
p_process_declarative_part(tree_t proc)3872 static void p_process_declarative_part(tree_t proc)
3873 {
3874    // { process_declarative_item }
3875 
3876    BEGIN("process declarative part");
3877 
3878    while (not_at_token(tBEGIN))
3879       p_process_declarative_item(proc);
3880 }
3881 
p_process_statement_part(tree_t proc)3882 static void p_process_statement_part(tree_t proc)
3883 {
3884    // { sequential_statement }
3885 
3886    BEGIN("process statement part");
3887 
3888    p_sequence_of_statements(proc, tree_add_stmt);
3889 }
3890 
p_process_statement(ident_t label)3891 static tree_t p_process_statement(ident_t label)
3892 {
3893    // [ process_label : ] [ postponed ] process [ ( sensitivity_list ) ] [ is ]
3894    //   process_declarative_part begin process_statement_part end [ postponed ]
3895    //   process [ label ] ;
3896 
3897    EXTEND("process statement");
3898 
3899    tree_t t = tree_new(T_PROCESS);
3900 
3901    const bool postponed = optional(tPOSTPONED);
3902 
3903    consume(tPROCESS);
3904 
3905    if (optional(tLPAREN)) {
3906       p_sensitivity_list(t);
3907       consume(tRPAREN);
3908    }
3909 
3910    optional(tIS);
3911 
3912    p_process_declarative_part(t);
3913 
3914    consume(tBEGIN);
3915 
3916    p_process_statement_part(t);
3917 
3918    consume(tEND);
3919    if (postponed)
3920       optional(tPOSTPONED);
3921    consume(tPROCESS);
3922    p_trailing_label(label);
3923    consume(tSEMI);
3924 
3925    const loc_t *loc = CURRENT_LOC;
3926    tree_set_loc(t, loc);
3927 
3928    if (label == NULL) {
3929       label = loc_to_ident(loc);
3930       tree_set_flag(t, TREE_F_SYNTHETIC_NAME);
3931    }
3932    tree_set_ident(t, label);
3933 
3934    if (postponed)
3935       tree_set_flag(t, TREE_F_POSTPONED);
3936 
3937    return t;
3938 }
3939 
p_entity_statement(void)3940 static tree_t p_entity_statement(void)
3941 {
3942    // concurrent_assertion_statement | concurrent_procedure_call_statement
3943    //   | process_statement
3944 
3945    BEGIN("entity statement");
3946 
3947    ident_t label = NULL;
3948    if ((peek() == tID) && (peek_nth(2) == tCOLON)) {
3949       label = p_identifier();
3950       consume(tCOLON);
3951    }
3952 
3953    switch (peek()) {
3954    case tASSERT:
3955       return p_concurrent_assertion_statement(label);
3956 
3957    case tPROCESS:
3958       return p_process_statement(label);
3959 
3960    case tPOSTPONED:
3961       if (peek_nth(2) == tASSERT)
3962          return p_concurrent_assertion_statement(label);
3963       else
3964          return p_process_statement(label);
3965 
3966    default:
3967       expect(tASSERT, tPOSTPONED);
3968       return tree_new(T_NULL);
3969    }
3970 }
3971 
p_entity_statement_part(tree_t entity)3972 static void p_entity_statement_part(tree_t entity)
3973 {
3974    // { entity_statement }
3975 
3976    BEGIN("entity statement part");
3977 
3978    while (not_at_token(tEND))
3979       tree_add_stmt(entity, p_entity_statement());
3980 }
3981 
p_entity_declaration(tree_t unit)3982 static void p_entity_declaration(tree_t unit)
3983 {
3984    // entity identifier is entity_header entity_declarative_part
3985    //   [ begin entity_statement_part ] end [ entity ] [ entity_simple_name ] ;
3986 
3987    BEGIN("entity declaration");
3988 
3989    tree_change_kind(unit, T_ENTITY);
3990 
3991    consume(tENTITY);
3992 
3993    ident_t id = p_identifier();
3994    tree_set_ident(unit, id);
3995 
3996    consume(tIS);
3997 
3998    p_entity_header(unit);
3999    p_entity_declarative_part(unit);
4000 
4001    if (optional(tBEGIN))
4002       p_entity_statement_part(unit);
4003 
4004    consume(tEND);
4005    optional(tENTITY);
4006    p_trailing_label(id);
4007    consume(tSEMI);
4008 
4009    tree_set_loc(unit, CURRENT_LOC);
4010 }
4011 
p_component_declaration(void)4012 static tree_t p_component_declaration(void)
4013 {
4014    // component identifier [ is ] [ generic_clause ] [ port_clause ]
4015    //   end component [ simple_name ] ;
4016 
4017    BEGIN("component declaration");
4018 
4019    tree_t c = tree_new(T_COMPONENT);
4020 
4021    consume(tCOMPONENT);
4022    tree_set_ident(c, p_identifier());
4023    optional(tIS);
4024 
4025    if (peek() == tGENERIC)
4026       p_generic_clause(c);
4027 
4028    if (peek() == tPORT)
4029       p_port_clause(c);
4030 
4031    consume(tEND);
4032    consume(tCOMPONENT);
4033    p_trailing_label(tree_ident(c));
4034    consume(tSEMI);
4035 
4036    tree_set_loc(c, CURRENT_LOC);
4037    return c;
4038 }
4039 
p_package_declarative_item(tree_t pack)4040 static void p_package_declarative_item(tree_t pack)
4041 {
4042    // subprogram_declaration | type_declaration | subtype_declaration
4043    //   | constant_declaration | signal_declaration
4044    //   | shared_variable_declaration | file_declaration | alias_declaration
4045    //   | component_declaration | attribute_declaration
4046    //   | attribute_specification | disconnection_specification | use_clause
4047    //   | group_template_declaration | group_declaration
4048    //
4049 
4050    BEGIN("package declarative item");
4051 
4052    switch (peek()) {
4053    case tTYPE:
4054       tree_add_decl(pack, p_type_declaration());
4055       break;
4056 
4057    case tFUNCTION:
4058    case tPROCEDURE:
4059    case tIMPURE:
4060    case tPURE:
4061       {
4062          tree_t spec = p_subprogram_specification();
4063          if (peek() == tSEMI)
4064             tree_add_decl(pack, p_subprogram_declaration(spec));
4065          else
4066             tree_add_decl(pack, p_subprogram_body(spec));
4067       }
4068       break;
4069 
4070    case tSUBTYPE:
4071       tree_add_decl(pack, p_subtype_declaration());
4072       break;
4073 
4074    case tSIGNAL:
4075       p_signal_declaration(pack);
4076       break;
4077 
4078    case tATTRIBUTE:
4079       if (peek_nth(3) == tOF)
4080          p_attribute_specification(pack, tree_add_decl);
4081       else
4082          tree_add_decl(pack, p_attribute_declaration());
4083       break;
4084 
4085    case tCONSTANT:
4086       p_constant_declaration(pack);
4087       break;
4088 
4089    case tCOMPONENT:
4090       tree_add_decl(pack, p_component_declaration());
4091       break;
4092 
4093    case tFILE:
4094       p_file_declaration(pack);
4095       break;
4096 
4097    case tSHARED:
4098       p_variable_declaration(pack);
4099       break;
4100 
4101    case tALIAS:
4102       tree_add_decl(pack, p_alias_declaration());
4103       break;
4104 
4105    case tUSE:
4106       p_use_clause(pack, tree_add_decl);
4107       break;
4108 
4109    default:
4110       expect(tTYPE, tFUNCTION, tPROCEDURE, tIMPURE, tPURE, tSUBTYPE, tSIGNAL,
4111              tATTRIBUTE, tCONSTANT, tCOMPONENT, tFILE, tSHARED, tALIAS, tUSE);
4112    }
4113 }
4114 
p_package_declarative_part(tree_t pack)4115 static void p_package_declarative_part(tree_t pack)
4116 {
4117    // { package_declarative_item }
4118 
4119    BEGIN("package declarative part");
4120 
4121    while (not_at_token(tEND))
4122       p_package_declarative_item(pack);
4123 }
4124 
p_package_declaration(tree_t unit)4125 static void p_package_declaration(tree_t unit)
4126 {
4127    // package identifier is package_declarative_part end [ package ]
4128    //   [ simple_name ] ;
4129 
4130    BEGIN("package declaration");
4131 
4132    consume(tPACKAGE);
4133 
4134    tree_change_kind(unit, T_PACKAGE);
4135    tree_set_ident(unit, p_identifier());
4136 
4137    consume(tIS);
4138 
4139    p_package_declarative_part(unit);
4140 
4141    consume(tEND);
4142    optional(tPACKAGE);
4143    p_trailing_label(tree_ident(unit));
4144    consume(tSEMI);
4145 
4146    tree_set_loc(unit, CURRENT_LOC);
4147 }
4148 
p_instantiation_list(void)4149 static ident_list_t *p_instantiation_list(void)
4150 {
4151    // label { , label } | others | all
4152 
4153    switch (peek()) {
4154    case tID:
4155       return p_identifier_list();
4156 
4157    case tOTHERS:
4158       consume(tOTHERS);
4159       return NULL;
4160 
4161    case tALL:
4162       {
4163          consume(tALL);
4164 
4165          ident_list_t *result = NULL;
4166          ident_list_add(&result, all_i);
4167          return result;
4168       }
4169 
4170    default:
4171       expect(tID, tOTHERS, tALL);
4172       return NULL;
4173    }
4174 }
4175 
p_component_specification(ident_t * comp_name)4176 static ident_list_t *p_component_specification(ident_t *comp_name)
4177 {
4178    // instantiation_list : name
4179 
4180    BEGIN("component specification");
4181 
4182    ident_list_t *ids = p_instantiation_list();
4183    consume(tCOLON);
4184    *comp_name = p_identifier();
4185 
4186    return ids;
4187 }
4188 
p_port_map_aspect(tree_t inst)4189 static void p_port_map_aspect(tree_t inst)
4190 {
4191    // port map ( association_list )
4192 
4193    BEGIN("port map aspect");
4194 
4195    consume(tPORT);
4196    consume(tMAP);
4197    consume(tLPAREN);
4198 
4199    p_association_list(inst, tree_add_param);
4200 
4201    consume(tRPAREN);
4202 }
4203 
p_generic_map_aspect(tree_t inst)4204 static void p_generic_map_aspect(tree_t inst)
4205 {
4206    // generic map ( association_list )
4207 
4208    BEGIN("generic map aspect");
4209 
4210    consume(tGENERIC);
4211    consume(tMAP);
4212    consume(tLPAREN);
4213 
4214    p_association_list(inst, tree_add_genmap);
4215 
4216    consume(tRPAREN);
4217 }
4218 
p_entity_aspect(void)4219 static tree_t p_entity_aspect(void)
4220 {
4221    // entity name [ ( identifier) ] | configuration name | open
4222 
4223    switch (one_of(tENTITY, tCONFIGURATION, tOPEN)) {
4224    case tENTITY:
4225       {
4226          tree_t bind = tree_new(T_BINDING);
4227          tree_set_class(bind, C_ENTITY);
4228          tree_set_ident(bind, p_selected_identifier());
4229          if (optional(tLPAREN)) {
4230             tree_set_ident2(bind, p_identifier());
4231             consume(tRPAREN);
4232          }
4233 
4234          return bind;
4235       }
4236 
4237    case tCONFIGURATION:
4238       {
4239          tree_t bind = tree_new(T_BINDING);
4240          tree_set_class(bind, C_CONFIGURATION);
4241          tree_set_ident(bind, p_selected_identifier());
4242 
4243          return bind;
4244       }
4245 
4246    case tOPEN:
4247    default:
4248       return NULL;
4249    }
4250 }
4251 
p_binding_indication(void)4252 static tree_t p_binding_indication(void)
4253 {
4254    // [ use entity_aspect ] [ generic_map_aspect ] [ port_map_aspect ]
4255 
4256    BEGIN("binding indication");
4257 
4258    tree_t bind = NULL;
4259    if (optional(tUSE))
4260       bind = p_entity_aspect();
4261    else
4262       bind = tree_new(T_BINDING);
4263 
4264    if (peek() == tGENERIC) {
4265       assert(bind != NULL);   // XXX: check for open here
4266       p_generic_map_aspect(bind);
4267    }
4268 
4269    if (peek() == tPORT) {
4270       assert(bind != NULL);   // XXX: check for open here
4271       p_port_map_aspect(bind);
4272    }
4273 
4274    if (bind != NULL)
4275       tree_set_loc(bind, CURRENT_LOC);
4276 
4277    return bind;
4278 }
4279 
p_configuration_specification(tree_t parent)4280 static void p_configuration_specification(tree_t parent)
4281 {
4282    // for component_specification binding_indication ;
4283 
4284    BEGIN("configuration specification");
4285 
4286    consume(tFOR);
4287 
4288    ident_t comp_name;
4289    LOCAL_IDENT_LIST ids = p_component_specification(&comp_name);
4290 
4291    tree_t bind = p_binding_indication();
4292    consume(tSEMI);
4293 
4294    const loc_t *loc = CURRENT_LOC;
4295 
4296    if (ids != NULL) {
4297       for (ident_list_t *it = ids; it != NULL; it = it->next) {
4298          tree_t t = tree_new(T_SPEC);
4299          tree_set_loc(t, loc);
4300          tree_set_ident(t, it->ident);
4301          tree_set_ident2(t, comp_name);
4302          tree_set_value(t, bind);
4303 
4304          tree_add_decl(parent, t);
4305       }
4306    }
4307    else {
4308       // Instantiation list was "others"
4309       tree_t t = tree_new(T_SPEC);
4310       tree_set_loc(t, loc);
4311       tree_set_ident2(t, comp_name);
4312       tree_set_value(t, bind);
4313 
4314       tree_add_decl(parent, t);
4315    }
4316 }
4317 
p_configuration_declarative_part(tree_t unit)4318 static void p_configuration_declarative_part(tree_t unit)
4319 {
4320    // use_clause | attribute_specification | group_declaration
4321 
4322    BEGIN("configuration declarative part");
4323 
4324    switch (peek()) {
4325    case tUSE:
4326       p_use_clause(unit, tree_add_decl);
4327       break;
4328 
4329    case tATTRIBUTE:
4330       p_attribute_specification(unit, tree_add_decl);
4331       break;
4332 
4333    default:
4334       expect(tUSE, tATTRIBUTE);
4335    }
4336 }
4337 
p_component_configuration(tree_t unit)4338 static void p_component_configuration(tree_t unit)
4339 {
4340    // for component_specification [ binding_indication ; ]
4341    //   [ block_configuration ] end for ;
4342 
4343    BEGIN("component configuration");
4344 
4345    consume(tFOR);
4346 
4347    ident_t comp_name;
4348    LOCAL_IDENT_LIST ids = p_component_specification(&comp_name);
4349 
4350    // TODO: should be optional
4351    tree_t bind = p_binding_indication();
4352    consume(tSEMI);
4353 
4354    const loc_t *loc = CURRENT_LOC;
4355 
4356    if (ids != NULL) {
4357       for (ident_list_t *it = ids; it != NULL; it = it->next) {
4358          tree_t t = tree_new(T_SPEC);
4359          tree_set_loc(t, loc);
4360          tree_set_ident(t, it->ident);
4361          tree_set_ident2(t, comp_name);
4362          tree_set_value(t, bind);
4363 
4364          tree_add_decl(unit, t);
4365       }
4366    }
4367    else {
4368       // Instantiation list was "others"
4369       tree_t t = tree_new(T_SPEC);
4370       tree_set_loc(t, loc);
4371       tree_set_ident2(t, comp_name);
4372       tree_set_value(t, bind);
4373 
4374       tree_add_decl(unit, t);
4375    }
4376 
4377    // TODO: optional block_configuration
4378 
4379    consume(tEND);
4380    consume(tFOR);
4381    consume(tSEMI);
4382 }
4383 
p_configuration_item(tree_t unit)4384 static void p_configuration_item(tree_t unit)
4385 {
4386    // block_configuration | component_configuration
4387 
4388    BEGIN("configuration item");
4389 
4390    const token_t third = peek_nth(3);
4391    if ((third == tCOLON) || (third == tCOMMA))
4392       p_component_configuration(unit);
4393    else
4394       tree_add_decl(unit, p_block_configuration());
4395 }
4396 
p_index_specification(void)4397 static void p_index_specification(void)
4398 {
4399    // discrete_range | expression
4400 
4401    const look_params_t lookp = {
4402       .look     = { tDOWNTO, tTO, tRANGE, tREVRANGE },
4403       .stop     = { tRPAREN, tCOMMA, tASSOC, tBAR },
4404       .abort    = tSEMI,
4405       .nest_in  = tLPAREN,
4406       .nest_out = tRPAREN,
4407       .depth    = 0
4408    };
4409 
4410    if (look_for(&lookp)) {
4411       p_discrete_range();
4412    }
4413    else {
4414       p_expression();
4415    }
4416 }
4417 
p_block_specification(tree_t unit)4418 static void p_block_specification(tree_t unit)
4419 {
4420    // label | label [ ( index_specification ) ]
4421 
4422    BEGIN("block specification");
4423 
4424    tree_set_ident(unit, p_identifier());
4425 
4426    if (optional(tLPAREN)) {
4427       p_index_specification();
4428       consume(tRPAREN);
4429    }
4430 }
4431 
p_block_configuration(void)4432 static tree_t p_block_configuration(void)
4433 {
4434    // for block_specification { use_clause } { configuration_item } end for ;
4435 
4436    BEGIN("block configuration");
4437 
4438    consume(tFOR);
4439 
4440    tree_t b = tree_new(T_BLOCK_CONFIG);
4441 
4442    p_block_specification(b);
4443 
4444    while (not_at_token(tEND))
4445       p_configuration_item(b);
4446 
4447    consume(tEND);
4448    consume(tFOR);
4449    consume(tSEMI);
4450 
4451    return b;
4452 }
4453 
p_configuration_declaration(tree_t unit)4454 static void p_configuration_declaration(tree_t unit)
4455 {
4456    // configuration identifier of name is configuration_declarative_part
4457    //   block_configuration end [ configuration ] [ simple_name ] ;
4458 
4459    BEGIN("configuration declaration");
4460 
4461    consume(tCONFIGURATION);
4462 
4463    tree_change_kind(unit, T_CONFIGURATION);
4464    tree_set_ident(unit, p_identifier());
4465 
4466    consume(tOF);
4467 
4468    tree_set_ident2(unit, p_identifier());
4469 
4470    consume(tIS);
4471 
4472    while (not_at_token(tFOR))
4473       p_configuration_declarative_part(unit);
4474 
4475    tree_add_decl(unit, p_block_configuration());
4476 
4477    consume(tEND);
4478    optional(tCONFIGURATION);
4479    p_trailing_label(tree_ident(unit));
4480    consume(tSEMI);
4481 
4482    tree_set_loc(unit, CURRENT_LOC);
4483 }
4484 
p_context_declaration(tree_t unit)4485 static void p_context_declaration(tree_t unit)
4486 {
4487    // 2008: context identifier is context_clause end [ context ]
4488    //       [ context_simple_name ] ;
4489 
4490    BEGIN("context declaration");
4491 
4492    consume(tCONTEXT);
4493 
4494    tree_change_kind(unit, T_CONTEXT);
4495    tree_set_ident(unit, p_identifier());
4496 
4497    consume(tIS);
4498 
4499    // LRM 08 section 13.1 forbids preceeding context clause
4500    if (tree_contexts(unit) != 2)     // Implicit WORK and STD
4501       parse_error(tree_loc(tree_context(unit, 2)), "context clause preceeding "
4502                   "context declaration must be empty");
4503 
4504    p_context_clause(unit);
4505 
4506    consume(tEND);
4507    optional(tCONTEXT);
4508    p_trailing_label(tree_ident(unit));
4509    consume(tSEMI);
4510 
4511    tree_set_loc(unit, CURRENT_LOC);
4512 }
4513 
p_primary_unit(tree_t unit)4514 static void p_primary_unit(tree_t unit)
4515 {
4516    // entity_declaration | configuration_declaration | package_declaration
4517 
4518    BEGIN("primary unit");
4519 
4520    switch (peek()) {
4521    case tENTITY:
4522       p_entity_declaration(unit);
4523       break;
4524 
4525    case tPACKAGE:
4526       p_package_declaration(unit);
4527       break;
4528 
4529    case tCONFIGURATION:
4530       p_configuration_declaration(unit);
4531       break;
4532 
4533    case tCONTEXT:
4534       p_context_declaration(unit);
4535       break;
4536 
4537    default:
4538       expect(tENTITY, tPACKAGE, tCONFIGURATION);
4539    }
4540 }
4541 
p_block_declarative_item(tree_t parent)4542 static void p_block_declarative_item(tree_t parent)
4543 {
4544    // subprogram_declaration | subprogram_body | type_declaration
4545    //   | subtype_declaration | constant_declaration | signal_declaration
4546    //   | shared_variable_declaration | file_declaration | alias_declaration
4547    //   | component_declaration | attribute_declaration
4548    //   | attribute_specification | configuration_specification
4549    //   | disconnection_specification | use_clause | group_template_declaration
4550    //   | group_declaration
4551 
4552    BEGIN("block declarative item");
4553 
4554    switch (peek()) {
4555    case tSIGNAL:
4556       p_signal_declaration(parent);
4557       break;
4558 
4559    case tTYPE:
4560       tree_add_decl(parent, p_type_declaration());
4561       break;
4562 
4563    case tSUBTYPE:
4564       tree_add_decl(parent, p_subtype_declaration());
4565       break;
4566 
4567    case tFILE:
4568       p_file_declaration(parent);
4569       break;
4570 
4571    case tCONSTANT:
4572       p_constant_declaration(parent);
4573       break;
4574 
4575    case tFUNCTION:
4576    case tPROCEDURE:
4577    case tIMPURE:
4578    case tPURE:
4579       {
4580          tree_t spec = p_subprogram_specification();
4581          if (peek() == tSEMI)
4582             tree_add_decl(parent, p_subprogram_declaration(spec));
4583          else
4584             tree_add_decl(parent, p_subprogram_body(spec));
4585       }
4586       break;
4587 
4588    case tALIAS:
4589       tree_add_decl(parent, p_alias_declaration());
4590       break;
4591 
4592    case tATTRIBUTE:
4593       if (peek_nth(3) == tOF)
4594          p_attribute_specification(parent, tree_add_decl);
4595       else
4596          tree_add_decl(parent, p_attribute_declaration());
4597       break;
4598 
4599    case tFOR:
4600       p_configuration_specification(parent);
4601       break;
4602 
4603    case tCOMPONENT:
4604       tree_add_decl(parent, p_component_declaration());
4605       break;
4606 
4607    case tUSE:
4608       p_use_clause(parent, tree_add_decl);
4609       break;
4610 
4611    case tSHARED:
4612       p_variable_declaration(parent);
4613       break;
4614 
4615    default:
4616       expect(tSIGNAL, tTYPE, tSUBTYPE, tFILE, tCONSTANT, tFUNCTION, tIMPURE,
4617              tPURE, tPROCEDURE, tALIAS, tATTRIBUTE, tFOR, tCOMPONENT, tUSE,
4618              tSHARED);
4619    }
4620 }
4621 
p_target(tree_t name)4622 static tree_t p_target(tree_t name)
4623 {
4624    // name | aggregate
4625 
4626    BEGIN("target");
4627 
4628    if (name == NULL) {
4629       if (peek() == tLPAREN)
4630          return p_aggregate();
4631       else
4632          return p_name();
4633    }
4634    else
4635       return name;
4636 }
4637 
p_variable_assignment_statement(ident_t label,tree_t name)4638 static tree_t p_variable_assignment_statement(ident_t label, tree_t name)
4639 {
4640    // [ label : ] target := expression ;
4641 
4642    EXTEND("variable assignment statement");
4643 
4644    tree_t t = tree_new(T_VAR_ASSIGN);
4645 
4646    tree_set_target(t, p_target(name));
4647 
4648    consume(tASSIGN);
4649 
4650    tree_set_value(t, p_expression());
4651 
4652    consume(tSEMI);
4653 
4654    const loc_t *loc = CURRENT_LOC;
4655    tree_set_loc(t, loc);
4656 
4657    if (label == NULL)
4658       label = loc_to_ident(loc);
4659    tree_set_ident(t, label);
4660 
4661    return t;
4662 }
4663 
p_waveform_element(void)4664 static tree_t p_waveform_element(void)
4665 {
4666    // expression [ after expression ] | null [ after expression ]
4667 
4668    BEGIN("waveform element");
4669 
4670    tree_t w = tree_new(T_WAVEFORM);
4671    tree_set_value(w, p_expression());
4672 
4673    if (optional(tAFTER))
4674       tree_set_delay(w, p_expression());
4675 
4676    tree_set_loc(w, CURRENT_LOC);
4677 
4678    return w;
4679 }
4680 
p_waveform(tree_t stmt)4681 static void p_waveform(tree_t stmt)
4682 {
4683    // waveform_element { , waveform_element } | unaffected
4684 
4685    BEGIN("waveform");
4686 
4687    if (optional(tUNAFFECTED))
4688       return;
4689 
4690    tree_add_waveform(stmt, p_waveform_element());
4691 
4692    while (optional(tCOMMA))
4693       tree_add_waveform(stmt, p_waveform_element());
4694 }
4695 
p_delay_mechanism(void)4696 static tree_t p_delay_mechanism(void)
4697 {
4698    // transport | [ reject expression ] inertial
4699 
4700    BEGIN("delay mechanism");
4701 
4702    switch (peek()) {
4703    case tTRANSPORT:
4704       consume(tTRANSPORT);
4705       return get_time(0);
4706 
4707    case tREJECT:
4708       {
4709          consume(tREJECT);
4710          tree_t t = p_expression();
4711          consume(tINERTIAL);
4712          return t;
4713       }
4714 
4715    case tINERTIAL:
4716       consume(tINERTIAL);
4717       return NULL;
4718 
4719    default:
4720       return NULL;
4721    }
4722 }
4723 
p_signal_assignment_statement(ident_t label,tree_t name)4724 static tree_t p_signal_assignment_statement(ident_t label, tree_t name)
4725 {
4726    // [ label : ] target <= [ delay_mechanism ] waveform ;
4727 
4728    EXTEND("signal assignment statement");
4729 
4730    tree_t t = tree_new(T_SIGNAL_ASSIGN);
4731 
4732    tree_set_target(t, p_target(name));
4733 
4734    consume(tLE);
4735 
4736    tree_t reject = p_delay_mechanism();
4737 
4738    p_waveform(t);
4739 
4740    consume(tSEMI);
4741 
4742    set_delay_mechanism(t, reject);
4743    set_label_and_loc(t, label, CURRENT_LOC);
4744    return t;
4745 }
4746 
p_sensitivity_clause(tree_t wait)4747 static void p_sensitivity_clause(tree_t wait)
4748 {
4749    // on sensitivity_list
4750 
4751    BEGIN("sensitivity clause");
4752 
4753    consume(tON);
4754    p_sensitivity_list(wait);
4755 }
4756 
p_condition_clause(tree_t wait)4757 static void p_condition_clause(tree_t wait)
4758 {
4759    // until condition
4760 
4761    BEGIN("condition clause");
4762 
4763    consume(tUNTIL);
4764    tree_set_value(wait, p_expression());
4765 }
4766 
p_timeout_clause(tree_t wait)4767 static void p_timeout_clause(tree_t wait)
4768 {
4769    // for expression
4770 
4771    BEGIN("timeout clause");
4772 
4773    consume(tFOR);
4774    tree_set_delay(wait, p_expression());
4775 }
4776 
p_wait_statement(ident_t label)4777 static tree_t p_wait_statement(ident_t label)
4778 {
4779    // [ label : ] wait [ sensitivity_clause ] [ condition_clause ]
4780    //   [ timeout_clause ] ;
4781 
4782    EXTEND("wait statement");
4783 
4784    tree_t t = tree_new(T_WAIT);
4785 
4786    consume(tWAIT);
4787 
4788    if (peek() == tON)
4789       p_sensitivity_clause(t);
4790 
4791    if (peek() == tUNTIL)
4792       p_condition_clause(t);
4793 
4794    if (peek() == tFOR)
4795       p_timeout_clause(t);
4796 
4797    consume(tSEMI);
4798 
4799    set_label_and_loc(t, label, CURRENT_LOC);
4800    return t;
4801 }
4802 
p_assertion_statement(ident_t label)4803 static tree_t p_assertion_statement(ident_t label)
4804 {
4805    // [ label : ] assertion ;
4806 
4807    EXTEND("assertion statement");
4808 
4809    tree_t t = p_assertion();
4810    consume(tSEMI);
4811 
4812    set_label_and_loc(t, label, CURRENT_LOC);
4813    return t;
4814 }
4815 
p_report_statement(ident_t label)4816 static tree_t p_report_statement(ident_t label)
4817 {
4818    // [ label : ] report expression [ severity expression ] ;
4819 
4820    EXTEND("report statement");
4821 
4822    tree_t t = tree_new(T_ASSERT);
4823 
4824    consume(tREPORT);
4825 
4826    tree_set_message(t, p_expression());
4827 
4828    if (optional(tSEVERITY))
4829       tree_set_severity(t, p_expression());
4830    else {
4831       tree_t sev = tree_new(T_REF);
4832       tree_set_ident(sev, ident_new("NOTE"));
4833 
4834       tree_set_severity(t, sev);
4835    }
4836 
4837    consume(tSEMI);
4838 
4839    tree_add_attr_int(t, ident_new("is_report"), 1);
4840 
4841    set_label_and_loc(t, label, CURRENT_LOC);
4842    return t;
4843 }
4844 
p_if_statement(ident_t label)4845 static tree_t p_if_statement(ident_t label)
4846 {
4847    // [ label : ] if condition then sequence_of_statements
4848    //   { elsif condition then sequence_of_statements }
4849    //   [ else sequence_of_statements ] end if [ label ] ;
4850 
4851    EXTEND("if statement");
4852 
4853    tree_t t = tree_new(T_IF);
4854 
4855    consume(tIF);
4856 
4857    tree_set_value(t, p_expression());
4858 
4859    consume(tTHEN);
4860 
4861    p_sequence_of_statements(t, tree_add_stmt);
4862 
4863    tree_t tail = t;
4864 
4865    while (optional(tELSIF)) {
4866       tree_t elsif = tree_new(T_IF);
4867       tree_set_ident(elsif, ident_uniq("elsif"));
4868       tree_set_value(elsif, p_expression());
4869 
4870       consume(tTHEN);
4871 
4872       p_sequence_of_statements(elsif, tree_add_stmt);
4873 
4874       tree_set_loc(elsif, CURRENT_LOC);
4875 
4876       tree_add_else_stmt(tail, elsif);
4877       tail = elsif;
4878    }
4879 
4880    if (optional(tELSE))
4881       p_sequence_of_statements(tail, tree_add_else_stmt);
4882 
4883    consume(tEND);
4884    consume(tIF);
4885    p_trailing_label(label);
4886    consume(tSEMI);
4887 
4888    set_label_and_loc(t, label, CURRENT_LOC);
4889    return t;
4890 }
4891 
p_null_statement(ident_t label)4892 static tree_t p_null_statement(ident_t label)
4893 {
4894    // [ label : ] null ;
4895 
4896    EXTEND("null statement");
4897 
4898    consume(tNULL);
4899    consume(tSEMI);
4900 
4901    tree_t t = tree_new(T_NULL);
4902    set_label_and_loc(t, label, CURRENT_LOC);
4903    return t;
4904 }
4905 
p_parameter_specification(tree_t loop)4906 static void p_parameter_specification(tree_t loop)
4907 {
4908    // identifier in discrete_range
4909 
4910    BEGIN("paremeter specification");
4911 
4912    tree_set_ident2(loop, p_identifier());
4913 
4914    consume(tIN);
4915 
4916    tree_add_range(loop, p_discrete_range());
4917 }
4918 
p_iteration_scheme(void)4919 static tree_t p_iteration_scheme(void)
4920 {
4921    // while condition | for parameter_specification
4922 
4923    BEGIN("iteration scheme");
4924 
4925    if (optional(tWHILE)) {
4926       tree_t t = tree_new(T_WHILE);
4927       tree_set_value(t, p_expression());
4928       return t;
4929    }
4930    else if (optional(tFOR)) {
4931       tree_t t = tree_new(T_FOR);
4932       p_parameter_specification(t);
4933       return t;
4934    }
4935    else {
4936       tree_t true_ref = tree_new(T_REF);
4937       tree_set_ident(true_ref, ident_new("TRUE"));
4938 
4939       tree_t t = tree_new(T_WHILE);
4940       tree_set_value(t, true_ref);
4941       return t;
4942    }
4943 }
4944 
p_loop_statement(ident_t label)4945 static tree_t p_loop_statement(ident_t label)
4946 {
4947    // [ loop_label : ] [ iteration_scheme ] loop sequence_of_statements
4948    //   end loop [ loop_label ] ;
4949 
4950    BEGIN("loop statement");
4951 
4952    tree_t t = p_iteration_scheme();
4953 
4954    consume(tLOOP);
4955 
4956    p_sequence_of_statements(t, tree_add_stmt);
4957 
4958    consume(tEND);
4959    consume(tLOOP);
4960    p_trailing_label(label);
4961    consume(tSEMI);
4962 
4963    set_label_and_loc(t, label, CURRENT_LOC);
4964    return t;
4965 }
4966 
p_return_statement(ident_t label)4967 static tree_t p_return_statement(ident_t label)
4968 {
4969    // [ label : ] return [ expression ] ;
4970 
4971    EXTEND("return statement");
4972 
4973    consume(tRETURN);
4974 
4975    tree_t t = tree_new(T_RETURN);
4976 
4977    if (peek() != tSEMI)
4978       tree_set_value(t, p_expression());
4979 
4980    consume(tSEMI);
4981 
4982    set_label_and_loc(t, label, CURRENT_LOC);
4983    return t;
4984 }
4985 
p_exit_statement(ident_t label)4986 static tree_t p_exit_statement(ident_t label)
4987 {
4988    // [ label : ] exit [ label ] [ when condition ] ;
4989 
4990    EXTEND("exit statement");
4991 
4992    consume(tEXIT);
4993 
4994    tree_t t = tree_new(T_EXIT);
4995 
4996    if (peek() == tID)
4997       tree_set_ident2(t, p_identifier());
4998 
4999    if (optional(tWHEN))
5000       tree_set_value(t, p_expression());
5001 
5002    consume(tSEMI);
5003 
5004    set_label_and_loc(t, label, CURRENT_LOC);
5005    return t;
5006 }
5007 
p_next_statement(ident_t label)5008 static tree_t p_next_statement(ident_t label)
5009 {
5010    // [ label : ] next [ label ] [ when condition ] ;
5011 
5012    EXTEND("next statement");
5013 
5014    consume(tNEXT);
5015 
5016    tree_t t = tree_new(T_NEXT);
5017 
5018    if (peek() == tID)
5019       tree_set_ident2(t, p_identifier());
5020 
5021    if (optional(tWHEN))
5022       tree_set_value(t, p_expression());
5023 
5024    consume(tSEMI);
5025 
5026    set_label_and_loc(t, label, CURRENT_LOC);
5027    return t;
5028 }
5029 
p_procedure_call_statement(ident_t label,tree_t name)5030 static tree_t p_procedure_call_statement(ident_t label, tree_t name)
5031 {
5032    // [ label : ] procedure_call ;
5033 
5034    EXTEND("procedure call statement");
5035 
5036    consume(tSEMI);
5037 
5038    tree_change_kind(name, T_PCALL);
5039    tree_set_ident2(name, tree_ident(name));
5040    set_label_and_loc(name, label, CURRENT_LOC);
5041    return name;
5042 }
5043 
p_case_statement_alternative(tree_t stmt)5044 static void p_case_statement_alternative(tree_t stmt)
5045 {
5046    // when choices => sequence_of_statements
5047 
5048    BEGIN("case statement alternative");
5049 
5050    consume(tWHEN);
5051 
5052    const int nstart = tree_assocs(stmt);
5053    p_choices(stmt);
5054 
5055    consume(tASSOC);
5056 
5057    tree_t b = tree_new(T_BLOCK);
5058    tree_set_ident(b, loc_to_ident(CURRENT_LOC));
5059    p_sequence_of_statements(b, tree_add_stmt);
5060 
5061    const int nassocs = tree_assocs(stmt);
5062    for (int i = nstart; i < nassocs; i++)
5063       tree_set_value(tree_assoc(stmt, i), b);
5064 }
5065 
p_case_statement(ident_t label)5066 static tree_t p_case_statement(ident_t label)
5067 {
5068    // [ label : ] case expression is case_statement_alternative
5069    //   { case_statement_alternative } end case [ label ] ;
5070 
5071    EXTEND("case statement");
5072 
5073    consume(tCASE);
5074 
5075    tree_t t = tree_new(T_CASE);
5076    tree_set_value(t, p_expression());
5077 
5078    consume(tIS);
5079 
5080    do {
5081       p_case_statement_alternative(t);
5082    } while (peek() == tWHEN);
5083 
5084    consume(tEND);
5085    consume(tCASE);
5086    p_trailing_label(label);
5087    consume(tSEMI);
5088 
5089    set_label_and_loc(t, label, CURRENT_LOC);
5090    return t;
5091 }
5092 
p_sequential_statement(void)5093 static tree_t p_sequential_statement(void)
5094 {
5095    // wait_statement | assertion_statement | report_statement
5096    //   | signal_assignment_statement | variable_assignment_statement
5097    //   | procedure_call_statement | if_statement | case_statement
5098    //   | loop_statement | next_statement | exit_statement | return_statement
5099    //   | null_statement
5100 
5101    BEGIN("sequential statement");
5102 
5103    if (peek() == tPRAGMA)
5104       return p_pragma();
5105 
5106    ident_t label = NULL;
5107    if ((peek() == tID) && (peek_nth(2) == tCOLON)) {
5108       label = p_identifier();
5109       consume(tCOLON);
5110    }
5111 
5112    switch (peek()) {
5113    case tWAIT:
5114       return p_wait_statement(label);
5115 
5116    case tASSERT:
5117       return p_assertion_statement(label);
5118 
5119    case tREPORT:
5120       return p_report_statement(label);
5121 
5122    case tIF:
5123       return p_if_statement(label);
5124 
5125    case tNULL:
5126       return p_null_statement(label);
5127 
5128    case tRETURN:
5129       return p_return_statement(label);
5130 
5131    case tCASE:
5132       return p_case_statement(label);
5133 
5134    case tWHILE:
5135    case tLOOP:
5136    case tFOR:
5137       return p_loop_statement(label);
5138 
5139    case tEXIT:
5140       return p_exit_statement(label);
5141 
5142    case tNEXT:
5143       return p_next_statement(label);
5144 
5145    case tID:
5146       break;
5147 
5148    case tLPAREN:
5149       {
5150          tree_t agg = p_aggregate();
5151 
5152          switch (peek()) {
5153          case tASSIGN:
5154             return p_variable_assignment_statement(label, agg);
5155 
5156          case tLE:
5157             return p_signal_assignment_statement(label, agg);
5158 
5159          default:
5160             expect(tASSIGN, tLE);
5161             return tree_new(T_NULL);
5162          }
5163       }
5164 
5165    default:
5166       expect(tWAIT, tID);
5167       drop_tokens_until(tSEMI);
5168       return tree_new(T_NULL);
5169    }
5170 
5171    tree_t name = p_name();
5172 
5173    switch (peek()) {
5174    case tASSIGN:
5175       return p_variable_assignment_statement(label, name);
5176 
5177    case tLE:
5178       return p_signal_assignment_statement(label, name);
5179 
5180    case tSEMI:
5181       return p_procedure_call_statement(label, name);
5182 
5183    default:
5184       expect(tASSIGN, tLE, tSEMI);
5185       drop_tokens_until(tSEMI);
5186       return tree_new(T_NULL);
5187    }
5188 }
5189 
p_instantiated_unit(void)5190 static tree_t p_instantiated_unit(void)
5191 {
5192    // [ component ] name
5193    //   | entity name [ ( identifier ) ]
5194    //   | configuration name
5195 
5196    BEGIN("instantiated unit");
5197 
5198    tree_t t = tree_new(T_INSTANCE);
5199 
5200    switch (peek()) {
5201    case tENTITY:
5202       consume(tENTITY);
5203       tree_set_class(t, C_ENTITY);
5204       break;
5205 
5206    case tCONFIGURATION:
5207       consume(tCONFIGURATION);
5208       tree_set_class(t, C_CONFIGURATION);
5209       break;
5210 
5211    case tCOMPONENT:
5212       consume(tCOMPONENT);
5213       // Fall-through
5214 
5215    default:
5216       tree_set_class(t, C_COMPONENT);
5217    }
5218 
5219    tree_set_ident2(t, p_selected_identifier());
5220 
5221    if ((tree_class(t) == C_ENTITY) && optional(tLPAREN)) {
5222       tree_set_ident2(t, ident_prefix(tree_ident2(t), p_identifier(), '-'));
5223       consume(tRPAREN);
5224    }
5225 
5226    return t;
5227 }
5228 
p_component_instantiation_statement(ident_t label)5229 static tree_t p_component_instantiation_statement(ident_t label)
5230 {
5231    // label : instantiated_unit [ generic_map_aspect ] [ port_map_aspect ] ;
5232 
5233    EXTEND("component instantiation statement");
5234 
5235    tree_t t = p_instantiated_unit();
5236    tree_set_ident(t, label);
5237 
5238    if (peek() == tGENERIC)
5239       p_generic_map_aspect(t);
5240 
5241    if (peek() == tPORT)
5242       p_port_map_aspect(t);
5243 
5244    consume(tSEMI);
5245 
5246    if (label == NULL)
5247       parse_error(CURRENT_LOC, "component instantiation statement must "
5248                   "have a label");
5249 
5250    tree_set_loc(t, CURRENT_LOC);
5251    return t;
5252 }
5253 
p_options(tree_t stmt)5254 static tree_t p_options(tree_t stmt)
5255 {
5256    // [ guarded ] [ delay_mechanism ]
5257 
5258    BEGIN("options");
5259 
5260    if (optional(tGUARDED))
5261       tree_set_flag(stmt, TREE_F_GUARDED);
5262 
5263    return p_delay_mechanism();
5264 }
5265 
p_conditional_waveforms(tree_t stmt)5266 static void p_conditional_waveforms(tree_t stmt)
5267 {
5268    // { waveform when condition else } waveform [ when condition ]
5269 
5270    BEGIN("conditional waveforms");
5271 
5272    for (;;) {
5273       tree_t c = tree_new(T_COND);
5274       p_waveform(c);
5275       tree_set_loc(c, CURRENT_LOC);
5276 
5277       tree_add_cond(stmt, c);
5278 
5279       if (optional(tWHEN)) {
5280          tree_set_value(c, p_expression());
5281 
5282          if (!optional(tELSE))
5283             break;
5284       }
5285       else
5286          break;
5287    }
5288 }
5289 
p_conditional_signal_assignment(void)5290 static tree_t p_conditional_signal_assignment(void)
5291 {
5292    // target <= options conditional_waveforms ;
5293 
5294    BEGIN("conditional signal assignment");
5295 
5296    tree_t t = tree_new(T_CASSIGN);
5297    tree_set_target(t, p_target(NULL));
5298 
5299    consume(tLE);
5300 
5301    tree_t reject = p_options(t);
5302    p_conditional_waveforms(t);
5303 
5304    const int nconds = tree_conds(t);
5305    for (int i = 0; i < nconds; i++)
5306       set_delay_mechanism(tree_cond(t, i), reject);
5307 
5308    consume(tSEMI);
5309 
5310    tree_set_loc(t, CURRENT_LOC);
5311    return t;
5312 }
5313 
p_selected_waveforms(tree_t stmt)5314 static void p_selected_waveforms(tree_t stmt)
5315 {
5316    // { waveform when choices , } waveform when choices
5317 
5318    BEGIN("selected waveforms");
5319 
5320    do {
5321       tree_t a = tree_new(T_SIGNAL_ASSIGN);
5322       p_waveform(a);
5323 
5324       consume(tWHEN);
5325 
5326       const int nstart = tree_assocs(stmt);
5327       p_choices(stmt);
5328 
5329       const int nassocs = tree_assocs(stmt);
5330       for (int i = nstart; i < nassocs; i++)
5331          tree_set_value(tree_assoc(stmt, i), a);
5332 
5333       tree_set_loc(a, CURRENT_LOC);
5334    } while (optional(tCOMMA));
5335 }
5336 
p_selected_signal_assignment(void)5337 static tree_t p_selected_signal_assignment(void)
5338 {
5339    // with expression select target <= options selected_waveforms ;
5340 
5341    BEGIN("selected signal assignment");
5342 
5343    consume(tWITH);
5344 
5345    tree_t t = tree_new(T_SELECT);
5346    tree_set_value(t, p_expression());
5347 
5348    consume(tSELECT);
5349    tree_t target = p_target(NULL);
5350    consume(tLE);
5351    tree_t reject = p_options(t);
5352    p_selected_waveforms(t);
5353    consume(tSEMI);
5354 
5355    const int nassocs = tree_assocs(t);
5356    for (int i = 0; i < nassocs; i++) {
5357       tree_t s = tree_value(tree_assoc(t, i));
5358       tree_set_target(s, target);
5359       set_delay_mechanism(s, reject);
5360    }
5361 
5362    tree_set_loc(t, CURRENT_LOC);
5363    return t;
5364 }
5365 
p_concurrent_signal_assignment_statement(ident_t label)5366 static tree_t p_concurrent_signal_assignment_statement(ident_t label)
5367 {
5368    // [ label : ] [ postponed ] conditional_signal_assignment
5369    //   | [ label : ] [ postponed ] selected_signal_assignment
5370 
5371    EXTEND("concurrent signal assignment statement");
5372 
5373    const bool postponed = optional(tPOSTPONED);
5374 
5375    tree_t t = (peek() == tWITH)
5376       ? p_selected_signal_assignment()
5377       : p_conditional_signal_assignment();
5378 
5379    const loc_t *loc = CURRENT_LOC;
5380    tree_set_loc(t, loc);
5381 
5382    if (label == NULL)
5383       label = loc_to_ident(loc);
5384    tree_set_ident(t, label);
5385 
5386    if (postponed)
5387       tree_set_flag(t, TREE_F_POSTPONED);
5388 
5389    tree_set_loc(t, CURRENT_LOC);
5390    return t;
5391 }
5392 
p_concurrent_procedure_call_statement(ident_t label)5393 static tree_t p_concurrent_procedure_call_statement(ident_t label)
5394 {
5395    // [ label : ] [ postponed ] procedure_call ;
5396 
5397    EXTEND("concurrent procedure call statement");
5398 
5399    const bool postponed = optional(tPOSTPONED);
5400 
5401    tree_t t = p_name();
5402 
5403    const tree_kind_t kind = tree_kind(t);
5404    if (kind != T_REF && kind != T_FCALL) {
5405       // This can only happen due to some earlier parsing error
5406       assert(n_errors > 0);
5407       return tree_new(T_CPCALL);
5408    }
5409 
5410    tree_change_kind(t, T_CPCALL);
5411    tree_set_ident2(t, tree_ident(t));
5412 
5413    consume(tSEMI);
5414 
5415    if (postponed)
5416       tree_set_flag(t, TREE_F_POSTPONED);
5417 
5418    const loc_t *loc = CURRENT_LOC;
5419    tree_set_loc(t, loc);
5420 
5421    if (label == NULL)
5422       label = loc_to_ident(loc);
5423    tree_set_ident(t, label);
5424 
5425    return t;
5426 }
5427 
p_block_statement_part(tree_t arch)5428 static void p_block_statement_part(tree_t arch)
5429 {
5430    // { concurrent_statement }
5431 
5432    BEGIN("block statement part");
5433 
5434    while (not_at_token(tEND))
5435       tree_add_stmt(arch, p_concurrent_statement());
5436 }
5437 
p_block_declarative_part(tree_t arch)5438 static void p_block_declarative_part(tree_t arch)
5439 {
5440    // { block_declarative_item }
5441 
5442    BEGIN("block declarative part");
5443 
5444    while (not_at_token(tBEGIN))
5445       p_block_declarative_item(arch);
5446 }
5447 
p_block_statement(ident_t label)5448 static tree_t p_block_statement(ident_t label)
5449 {
5450    // label : block [ ( expression ) ] [ is ] block_header
5451    //   block_declarative_part begin block_statement_part end block [ label ] ;
5452 
5453    EXTEND("block statement");
5454 
5455    tree_t b = tree_new(T_BLOCK);
5456    tree_set_ident(b, label);
5457 
5458    consume(tBLOCK);
5459    optional(tIS);
5460    p_block_declarative_part(b);
5461    consume(tBEGIN);
5462    p_block_statement_part(b);
5463    consume(tEND);
5464    consume(tBLOCK);
5465    p_trailing_label(label);
5466    consume(tSEMI);
5467 
5468    if (label == NULL)
5469       parse_error(CURRENT_LOC, "block statement must have a label");
5470 
5471    tree_set_loc(b, CURRENT_LOC);
5472    return b;
5473 }
5474 
p_generation_scheme(void)5475 static tree_t p_generation_scheme(void)
5476 {
5477    // for parameter_specification | if condition
5478 
5479    BEGIN("generation scheme");
5480 
5481    switch (one_of(tIF, tFOR)) {
5482    case tIF:
5483       {
5484          tree_t g = tree_new(T_IF_GENERATE);
5485          tree_set_value(g, p_expression());
5486          return g;
5487       }
5488 
5489    case tFOR:
5490       {
5491          tree_t g = tree_new(T_FOR_GENERATE);
5492          p_parameter_specification(g);
5493          return g;
5494       }
5495 
5496    default:
5497       return tree_new(T_IF_GENERATE);
5498    }
5499 }
5500 
p_generate_statement(ident_t label)5501 static tree_t p_generate_statement(ident_t label)
5502 {
5503    // label : generation_scheme generate [ { block_declarative_item }
5504    //   begin ] { concurrent_statement } end generate [ label ] ;
5505 
5506    EXTEND("generate statement");
5507 
5508    tree_t g = p_generation_scheme();
5509    tree_set_ident(g, label);
5510 
5511    consume(tGENERATE);
5512 
5513    if (scan(tSIGNAL, tTYPE, tSUBTYPE, tFILE, tCONSTANT, tFUNCTION, tIMPURE,
5514             tPURE, tALIAS, tATTRIBUTE, tBEGIN, tPROCEDURE, tFOR, tCOMPONENT,
5515             tUSE, tSHARED)) {
5516       while (not_at_token(tBEGIN))
5517          p_block_declarative_item(g);
5518       consume(tBEGIN);
5519    }
5520 
5521    while (not_at_token(tEND))
5522       tree_add_stmt(g, p_concurrent_statement());
5523 
5524    consume(tEND);
5525    consume(tGENERATE);
5526    p_trailing_label(label);
5527    consume(tSEMI);
5528 
5529    if (label == NULL)
5530       parse_error(CURRENT_LOC, "generate statement must have a label");
5531 
5532    tree_set_loc(g, CURRENT_LOC);
5533    return g;
5534 }
5535 
p_concurrent_statement(void)5536 static tree_t p_concurrent_statement(void)
5537 {
5538    // block_statement | process_statement | concurrent_procedure_call_statement
5539    //   | concurrent_assertion_statement
5540    //   | concurrent_signal_assignment_statement
5541    //   | component_instantiation_statement | generate_statement
5542 
5543    BEGIN("concurrent statement");
5544 
5545    if (peek() == tPRAGMA)
5546       return p_pragma();
5547 
5548    ident_t label = NULL;
5549    if ((peek() == tID) && (peek_nth(2) == tCOLON)) {
5550       label = p_identifier();
5551       consume(tCOLON);
5552    }
5553 
5554    if (peek() == tID) {
5555       const token_t p2 = peek_nth(2);
5556       if (((label != NULL) && (p2 == tSEMI))
5557           || (p2 == tGENERIC) || (p2 == tPORT))
5558          return p_component_instantiation_statement(label);
5559       else {
5560          const look_params_t lookp = {
5561             .look     = { tLE },
5562             .stop     = { tSEMI },
5563             .nest_in  = tLPAREN,
5564             .nest_out = tRPAREN,
5565             .depth    = 0
5566          };
5567 
5568          if (look_for(&lookp))
5569             return p_concurrent_signal_assignment_statement(label);
5570          else
5571             return p_concurrent_procedure_call_statement(label);
5572       }
5573    }
5574    else {
5575       switch (peek()) {
5576       case tPROCESS:
5577          return p_process_statement(label);
5578 
5579       case tCOMPONENT:
5580       case tENTITY:
5581       case tCONFIGURATION:
5582          return p_component_instantiation_statement(label);
5583 
5584       case tWITH:
5585          return p_concurrent_signal_assignment_statement(label);
5586 
5587       case tASSERT:
5588          return p_concurrent_assertion_statement(label);
5589 
5590       case tPOSTPONED:
5591          if (peek_nth(2) == tASSERT)
5592             return p_concurrent_assertion_statement(label);
5593          else
5594             return p_process_statement(label);
5595 
5596       case tBLOCK:
5597          return p_block_statement(label);
5598 
5599       case tIF:
5600       case tFOR:
5601          return p_generate_statement(label);
5602 
5603       case tLPAREN:
5604          return p_concurrent_signal_assignment_statement(label);
5605 
5606       default:
5607          expect(tPROCESS, tPOSTPONED, tCOMPONENT, tENTITY, tCONFIGURATION,
5608                 tWITH, tASSERT, tBLOCK, tIF, tFOR);
5609          drop_tokens_until(tSEMI);
5610          return tree_new(T_BLOCK);
5611       }
5612    }
5613 }
5614 
p_architecture_declarative_part(tree_t arch)5615 static void p_architecture_declarative_part(tree_t arch)
5616 {
5617    // { block_declarative_item }
5618 
5619    BEGIN("architecture declarative part");
5620 
5621    while (not_at_token(tBEGIN))
5622       p_block_declarative_item(arch);
5623 }
5624 
p_architecture_statement_part(tree_t arch)5625 static void p_architecture_statement_part(tree_t arch)
5626 {
5627    // { concurrent_statement }
5628 
5629    BEGIN("architecture statement part");
5630 
5631    while (not_at_token(tEND))
5632       tree_add_stmt(arch, p_concurrent_statement());
5633 }
5634 
p_architecture_body(tree_t unit)5635 static void p_architecture_body(tree_t unit)
5636 {
5637    // architecture identifier of entity_name is architecture_declarative_part
5638    //   begin architecture_statement_part end [ architecture ]
5639    //   [ architecture_simple_name ] ;
5640 
5641    BEGIN("architecture body");
5642 
5643    tree_change_kind(unit, T_ARCH);
5644 
5645    consume(tARCHITECTURE);
5646    tree_set_ident(unit, p_identifier());
5647    consume(tOF);
5648    tree_set_ident2(unit, p_identifier());
5649    consume(tIS);
5650 
5651    p_architecture_declarative_part(unit);
5652 
5653    consume(tBEGIN);
5654 
5655    p_architecture_statement_part(unit);
5656 
5657    consume(tEND);
5658    optional(tARCHITECTURE);
5659    p_trailing_label(tree_ident(unit));
5660    consume(tSEMI);
5661 
5662    tree_set_loc(unit, CURRENT_LOC);
5663 }
5664 
p_package_body_declarative_item(tree_t parent)5665 static void p_package_body_declarative_item(tree_t parent)
5666 {
5667    // subprogram_declaration | subprogram_body | type_declaration
5668    //   | subtype_declaration | constant_declaration
5669    //   | shared_variable_declaration | file_declaration | alias_declaration
5670    //   | use_clause | group_template_declaration | group_declaration
5671    //
5672    // 2008: subprogram_instantiation_declaration | attribute_declaration
5673    //         | attribute_specification | package_instantiation_declaration
5674 
5675    BEGIN("package body declarative item");
5676 
5677    switch (peek()) {
5678    case tFUNCTION:
5679    case tPROCEDURE:
5680    case tIMPURE:
5681    case tPURE:
5682       {
5683          tree_t spec = p_subprogram_specification();
5684          if (peek() == tSEMI)
5685             tree_add_decl(parent, p_subprogram_declaration(spec));
5686          else
5687             tree_add_decl(parent, p_subprogram_body(spec));
5688       }
5689       break;
5690 
5691    case tSHARED:
5692       p_variable_declaration(parent);
5693       break;
5694 
5695    case tFILE:
5696       p_file_declaration(parent);
5697       break;
5698 
5699    case tATTRIBUTE:
5700       if (standard() < STD_08)
5701          parse_error(CURRENT_LOC, "package body may not contain attribute "
5702                      "declarations or specifications in VHDL-%s",
5703                      standard_text(standard()));
5704       else {
5705          if (peek_nth(3) == tOF)
5706             p_attribute_specification(parent, tree_add_decl);
5707          else
5708             tree_add_decl(parent, p_attribute_declaration());
5709       }
5710       break;
5711 
5712    case tTYPE:
5713       tree_add_decl(parent, p_type_declaration());
5714       break;
5715 
5716    case tCONSTANT:
5717       p_constant_declaration(parent);
5718       break;
5719 
5720    case tSUBTYPE:
5721       tree_add_decl(parent, p_subtype_declaration());
5722       break;
5723 
5724    case tALIAS:
5725       tree_add_decl(parent, p_alias_declaration());
5726       break;
5727 
5728    case tUSE:
5729       p_use_clause(parent, tree_add_decl);
5730       break;
5731 
5732    default:
5733       expect(tFUNCTION, tPROCEDURE, tSHARED, tIMPURE, tPURE, tATTRIBUTE, tTYPE,
5734              tCONSTANT, tSUBTYPE, tFILE, tALIAS, tUSE);
5735    }
5736 }
5737 
p_package_body_declarative_part(tree_t unit)5738 static void p_package_body_declarative_part(tree_t unit)
5739 {
5740    // { package_body_declarative_item }
5741 
5742    BEGIN("package body declarative part");
5743 
5744    while (not_at_token(tEND))
5745       p_package_body_declarative_item(unit);
5746 }
5747 
p_package_body(tree_t unit)5748 static void p_package_body(tree_t unit)
5749 {
5750    // package body simple_name is package_body_declarative_part
5751    //   end [ package body ] [ simple_name ] ;
5752 
5753    BEGIN("package body");
5754 
5755    consume(tPACKAGE);
5756    consume(tBODY);
5757 
5758    tree_change_kind(unit, T_PACK_BODY);
5759    tree_set_ident(unit, p_identifier());
5760 
5761    consume(tIS);
5762 
5763    p_package_body_declarative_part(unit);
5764 
5765    consume(tEND);
5766 
5767    if (optional(tPACKAGE))
5768       consume(tBODY);
5769 
5770    p_trailing_label(tree_ident(unit));
5771    consume(tSEMI);
5772 
5773    tree_set_loc(unit, CURRENT_LOC);
5774 }
5775 
p_secondary_unit(tree_t unit)5776 static void p_secondary_unit(tree_t unit)
5777 {
5778    // architecture_body | package_body
5779 
5780    BEGIN("secondary unit");
5781 
5782    switch (peek()) {
5783    case tARCHITECTURE:
5784       p_architecture_body(unit);
5785       break;
5786 
5787    case tPACKAGE:
5788       p_package_body(unit);
5789       break;
5790 
5791    default:
5792       expect(tARCHITECTURE, tPACKAGE);
5793    }
5794 }
5795 
p_library_unit(tree_t unit)5796 static void p_library_unit(tree_t unit)
5797 {
5798    // primary_unit | secondary_unit
5799 
5800    BEGIN("library unit");
5801 
5802    switch (peek()) {
5803    case tENTITY:
5804    case tCONFIGURATION:
5805    case tCONTEXT:
5806       p_primary_unit(unit);
5807       break;
5808 
5809    case tARCHITECTURE:
5810       p_secondary_unit(unit);
5811       break;
5812 
5813    case tPACKAGE:
5814       if (peek_nth(2) == tBODY)
5815          p_secondary_unit(unit);
5816       else
5817          p_primary_unit(unit);
5818       break;
5819 
5820    default:
5821       expect(tENTITY, tCONFIGURATION, tARCHITECTURE, tPACKAGE, tCONTEXT);
5822    }
5823 }
5824 
p_design_unit(void)5825 static tree_t p_design_unit(void)
5826 {
5827    BEGIN("design unit");
5828 
5829    tree_t unit = tree_new(T_DESIGN_UNIT);
5830 
5831    tree_t std = tree_new(T_LIBRARY);
5832    tree_set_ident(std, std_i);
5833    tree_add_context(unit, std);
5834 
5835    tree_t work = tree_new(T_LIBRARY);
5836    tree_set_ident(work, lib_name(lib_work()));
5837    tree_add_context(unit, work);
5838 
5839    p_context_clause(unit);
5840    p_library_unit(unit);
5841 
5842    return unit;
5843 }
5844 
begin_token(char * tok)5845 void begin_token(char *tok)
5846 {
5847    const char *newline = strrchr(tok, '\n');
5848    int n_token_start, n_token_length;
5849    if (newline != NULL) {
5850       n_token_start = 0;
5851       n_token_length = strlen(tok) - (newline - tok);
5852       n_token_next_start = n_token_length - 1;
5853    }
5854    else {
5855       n_token_start = n_token_next_start;
5856       n_token_length = strlen(tok);
5857       n_token_next_start += n_token_length;
5858    }
5859 
5860    const int last_col = n_token_start + n_token_length - 1;
5861 
5862    yylloc.first_line   = MIN(n_row, LINE_INVALID);
5863    yylloc.first_column = MIN(n_token_start, COLUMN_INVALID);
5864    yylloc.last_line    = MIN(n_row, LINE_INVALID);
5865    yylloc.last_column  = MIN(last_col, COLUMN_INVALID);
5866    yylloc.file         = perm_file_name;
5867    yylloc.linebuf      = perm_linebuf;
5868 }
5869 
get_next_char(char * b,int max_buffer)5870 int get_next_char(char *b, int max_buffer)
5871 {
5872    if (last_was_newline) {
5873       n_row += 1;
5874       perm_linebuf = read_ptr;
5875       last_was_newline = false;
5876    }
5877 
5878    const bool eof = read_ptr >= file_start + file_sz;
5879    if (eof)
5880       return 0;
5881    else
5882       *b = *read_ptr++;
5883 
5884    if (perm_linebuf == NULL)
5885       perm_linebuf = read_ptr;
5886 
5887    if (*b == '\n')
5888       last_was_newline = true;
5889 
5890    return *b == 0 ? 0 : 1;
5891 }
5892 
input_from_file(const char * file)5893 void input_from_file(const char *file)
5894 {
5895    int fd = open(file, O_RDONLY);
5896    if (fd < 0)
5897       fatal_errno("opening %s", file);
5898 
5899    struct stat buf;
5900    if (fstat(fd, &buf) != 0)
5901       fatal_errno("fstat");
5902 
5903    if (!S_ISREG(buf.st_mode))
5904       fatal("opening %s: not a regular file", file);
5905 
5906    file_sz = buf.st_size;
5907 
5908    if (file_sz > 0)
5909       file_start = map_file(fd, file_sz);
5910    else
5911       file_start = NULL;
5912 
5913    read_ptr           = file_start;
5914    last_was_newline   = true;
5915    perm_file_name     = ident_new(file);
5916    n_row              = 0;
5917    n_token_next_start = 0;
5918    translate_on       = true;
5919    parse_pragmas      = opt_get_int("parse-pragmas");
5920 
5921    if (tokenq == NULL) {
5922       tokenq_sz = 128;
5923       tokenq = xmalloc(tokenq_sz * sizeof(tokenq_t));
5924    }
5925 
5926    tokenq_head = tokenq_tail = 0;
5927 }
5928 
parse(void)5929 tree_t parse(void)
5930 {
5931    int old_errors = n_errors;
5932    n_correct = RECOVER_THRESH;
5933 
5934    if (peek() == tEOF)
5935       return NULL;
5936 
5937    tree_t unit = p_design_unit();
5938 
5939    while (cond_state != NULL) {
5940       cond_state_t *tmp = cond_state->next;
5941       free(cond_state);
5942       cond_state = tmp;
5943    }
5944 
5945    if (n_errors > old_errors)
5946       return NULL;
5947    else
5948       return unit;
5949 }
5950 
parse_errors(void)5951 int parse_errors(void)
5952 {
5953    return n_errors;
5954 }
5955 
reset_parse_errors(void)5956 void reset_parse_errors(void)
5957 {
5958    n_errors = 0;
5959 }
5960