-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathparser.y
4469 lines (3811 loc) · 117 KB
/
parser.y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
%{
/*******************************************************************\
Module: Verilog Parser
Author: Daniel Kroening, [email protected]
\*******************************************************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <util/arith_tools.h>
#include <util/ebmc_util.h>
#include <util/mathematical_types.h>
#include <util/std_expr.h>
#include "verilog_parser.h"
#define PARSER (*verilog_parser_ptr)
#define YYSTYPE unsigned
#define YYSTYPE_IS_TRIVIAL 1
//#define YYDEBUG 1
#define mto(x, y) stack_expr(x).add_to_operands(std::move(stack_expr(y)))
#define mts(x, y) stack_expr(x).move_to_sub((irept &)stack_expr(y))
#define swapop(x, y) stack_expr(x).operands().swap(stack_expr(y).operands())
#define addswap(x, y, z) stack_expr(x).add(y).swap(stack_expr(z))
#define push_scope(x, y) PARSER.push_scope(x, y)
#define pop_scope() PARSER.pop_scope();
int yyveriloglex();
extern char *yyverilogtext;
/*******************************************************************\
Function: init
Inputs:
Outputs:
Purpose:
\*******************************************************************/
inline static void init(exprt &expr)
{
expr.clear();
PARSER.set_source_location(expr);
}
/*******************************************************************\
Function: init
Inputs:
Outputs:
Purpose:
\*******************************************************************/
inline static void init(YYSTYPE &expr)
{
newstack(expr);
init(stack_expr(expr));
}
/*******************************************************************\
Function: make_nil
Inputs:
Outputs:
Purpose:
\*******************************************************************/
inline static void make_nil(YYSTYPE &expr)
{
newstack(expr);
stack_expr(expr).make_nil();
}
/*******************************************************************\
Function: init
Inputs:
Outputs:
Purpose:
\*******************************************************************/
inline static void init(YYSTYPE &expr, const irep_idt &id)
{
init(expr);
stack_expr(expr).id(id);
}
/*******************************************************************\
Function: new_symbol
Inputs:
Outputs:
Purpose:
\*******************************************************************/
inline static void new_symbol(YYSTYPE &dest, YYSTYPE &src)
{
init(dest, ID_symbol);
const auto base_name = stack_expr(src).id();
stack_expr(dest).set(ID_identifier, base_name);
stack_expr(dest).set(ID_base_name, base_name);
}
/*******************************************************************\
Function: add_as_subtype
Inputs:
Outputs:
Purpose:
\*******************************************************************/
static void add_as_subtype(typet &dest, typet &what)
{
// this is recursive and quadratic-time, so not super.
if(what.is_nil())
{
// do nothing
}
else if(dest.is_nil() || dest.id()==irep_idt())
dest.swap(what);
else
{
typet &subtype=to_type_with_subtype(dest).subtype();
add_as_subtype(subtype, what);
}
}
/*******************************************************************\
Function: add_attributes
Inputs:
Outputs:
Purpose:
\*******************************************************************/
static void add_attributes(YYSTYPE &dest, YYSTYPE &attributes)
{
PRECONDITION(stack_expr(attributes).id() == ID_verilog_attributes);
if(!stack_expr(attributes).get_sub().empty())
addswap(dest, ID_verilog_attributes, attributes);
}
/*******************************************************************\
Function: yyverilogerror
Inputs:
Outputs:
Purpose:
\*******************************************************************/
int yyverilogerror(const char *error)
{
PARSER.parse_error(error, yyverilogtext);
return strlen(error)+1;
}
%}
/* Grammar Selection */
%token TOK_PARSE_LANGUAGE
%token TOK_PARSE_EXPRESSION
%token TOK_PARSE_TYPE
/* Generic */
%token TOK_PARENASTERIC "(*"
%token TOK_ASTERICPAREN "*)"
/* Unary */
%token TOK_EXCLAM "!"
%token TOK_TILDE "~"
%token TOK_AMPER "&"
%token TOK_TILDEAMPER "~&"
%token TOK_TILDEVERTBAR "~|"
%token TOK_CARET "^"
%token TOK_TILDECARET "~^"
%token TOK_CARETTILDE "^~"
%token TOK_MINUSGREATER "->"
/* Binary */
%token TOK_ASTERIC "*"
%token TOK_SLASH "/"
%token TOK_PERCENT "%"
%token TOK_EQUALEQUAL "=="
%token TOK_EXCLAMEQUAL "!="
%token TOK_EQUALEQUALEQUAL "==="
%token TOK_EXCLAMEQUALEQUAL "!=="
%token TOK_AMPERAMPER "&&"
%token TOK_ASTERICASTERIC "**"
%token TOK_VERTBARVERTBAR "||"
%token TOK_LESS "<"
%token TOK_LESSEQUAL "<="
%token TOK_GREATER ">"
%token TOK_GREATEREQUAL ">="
%token TOK_GREATERGREATER ">>"
%token TOK_GREATERGREATERGREATER ">>>"
%token TOK_LESSLESS "<<"
%token TOK_LESSLESSLESS "<<<"
%token TOK_LESSMINUSGREATER "<->"
/* Unary or binary */
%token TOK_PLUS "+"
%token TOK_MINUS "-"
%token TOK_VERTBAR "|"
/* Ternary */
%token TOK_QUESTION "?"
%token TOK_COLON ":"
/* Keywords */
%token TOK_ALWAYS "always"
%token TOK_AND "and"
%token TOK_ASSIGN "assign"
%token TOK_AUTOMATIC "automatic"
%token TOK_BEGIN "begin"
%token TOK_BUF "buf"
%token TOK_BUFIF0 "bufif0"
%token TOK_BUFIF1 "bufif1"
%token TOK_CASE "case"
%token TOK_CASEX "casex"
%token TOK_CASEZ "casez"
%token TOK_CMOS "cmos"
%token TOK_DEASSIGN "deassign"
%token TOK_DEFAULT "default"
%token TOK_DEFPARAM "defparam"
%token TOK_DISABLE "disable"
%token TOK_EDGE "edge"
%token TOK_ELSE "else"
%token TOK_END "end"
%token TOK_ENDCASE "endcase"
%token TOK_ENDFUNCTION "endfunction"
%token TOK_ENDGENERATE "endgenerate"
%token TOK_ENDMODULE "endmodule"
%token TOK_ENDPRIMITIVE "endprimitive"
%token TOK_ENDSPECIFY "endspecify"
%token TOK_ENDTABLE "endtable"
%token TOK_ENDTASK "endtask"
%token TOK_EVENT "event"
%token TOK_FOR "for"
%token TOK_FORCE "force"
%token TOK_FOREVER "forever"
%token TOK_FORK "fork"
%token TOK_FUNCTION "function"
%token TOK_GENERATE "generate"
%token TOK_GENVAR "genvar"
%token TOK_HIGHZ0 "highz0"
%token TOK_HIGHZ1 "highz1"
%token TOK_IF "if"
%token TOK_IFNONE "ifnone"
%token TOK_INCDIR "incdir"
%token TOK_INCLUDE "include"
%token TOK_INITIAL "initial"
%token TOK_INOUT "inout"
%token TOK_INPUT "input"
%token TOK_INSTANCE "instance"
%token TOK_INTEGER "integer"
%token TOK_JOIN "join"
%token TOK_LARGE "large"
%token TOK_LIBLIST "liblist"
%token TOK_LIBRARY "library"
%token TOK_LOCALPARAM "localparam"
%token TOK_MACROMODULE "macromodule"
%token TOK_MEDIUM "medium"
%token TOK_MODULE "module"
%token TOK_NAND "nand"
%token TOK_NEGEDGE "negedge"
%token TOK_NMOS "nmos"
%token TOK_NOR "nor"
%token TOK_NOSHOWCANCELLED "noshowcancelled"
%token TOK_NOT "not"
%token TOK_NOTIF0 "notif0"
%token TOK_NOTIF1 "notif1"
%token TOK_OR "or"
%token TOK_OUTPUT "output"
%token TOK_PARAMETER "parameter"
%token TOK_PMOS "pmos"
%token TOK_POSEDGE "posedge"
%token TOK_PRIMITIVE "primitive"
%token TOK_PULL0 "pull0"
%token TOK_PULL1 "pull1"
%token TOK_PULLDOWN "pulldown"
%token TOK_PULLUP "pullup"
%token TOK_PULSESTYLE_ONDETECT "pulsestyle_ondetect"
%token TOK_PULSESTYLE_ONEVENT "pulsestyle_onevent"
%token TOK_RCMOS "rcmos"
%token TOK_REAL "real"
%token TOK_REALTIME "realtime"
%token TOK_REG "reg"
%token TOK_RELEASE "release"
%token TOK_REPEAT "repeat"
%token TOK_RNMOS "rnmos"
%token TOK_RPMOS "rpmos"
%token TOK_RTRAN "rtran"
%token TOK_RTRANIF0 "rtranif0"
%token TOK_RTRANIF1 "rtranif1"
%token TOK_SCALARED "scalared"
%token TOK_SIGNED "signed"
%token TOK_SMALL "small"
%token TOK_SPECIFY "specify"
%token TOK_SPECPARAM "specparam"
%token TOK_STRONG0 "strong0"
%token TOK_STRONG1 "strong1"
%token TOK_SUPPLY0 "supply0"
%token TOK_SUPPLY1 "supply1"
%token TOK_TABLE "table"
%token TOK_TASK "task"
%token TOK_TIME "time"
%token TOK_TRAN "tran"
%token TOK_TRANIF0 "tranif0"
%token TOK_TRANIF1 "tranif1"
%token TOK_TRI "tri"
%token TOK_TRI0 "tri0"
%token TOK_TRI1 "tri1"
%token TOK_TRIAND "triand"
%token TOK_TRIOR "trior"
%token TOK_TRIREG "trireg"
%token TOK_UNSIGNED "unsigned"
%token TOK_USE "use"
%token TOK_VECTORED "vectored"
%token TOK_WAIT "wait"
%token TOK_WAND "wand"
%token TOK_WEAK0 "weak0"
%token TOK_WEAK1 "weak1"
%token TOK_WHILE "while"
%token TOK_WIRE "wire"
%token TOK_WOR "wor"
%token TOK_XNOR "xnor"
%token TOK_XOR "xor"
%token TOK_SETUP "setup"
%token TOK_HOLD "hold"
%token TOK_RECOVERY "recovery"
%token TOK_REMOVAL "removal"
%token TOK_WIDTH "width"
%token TOK_SKEW "skew"
%token TOK_UWIRE "uwire"
/* System Verilog Operators */
%token TOK_VERTBARMINUSGREATER "|->"
%token TOK_VERTBAREQUALGREATER "|=>"
%token TOK_PLUSPLUS "++"
%token TOK_MINUSMINUS "--"
%token TOK_PLUSEQUAL "+="
%token TOK_PLUSCOLON "+:"
%token TOK_MINUSEQUAL "-="
%token TOK_MINUSCOLON "-:"
%token TOK_ASTERICEQUAL "*="
%token TOK_SLASHEQUAL "/="
%token TOK_PERCENTEQUAL "%="
%token TOK_AMPEREQUAL "&="
%token TOK_CARETEQUAL "^="
%token TOK_VERTBAREQUAL "|="
%token TOK_LESSLESSEQUAL "<<="
%token TOK_GREATERGREATEREQUAL ">>="
%token TOK_LESSLESSLESSEQUAL "<<<="
%token TOK_GREATERGREATERGREATEREQUAL ">>>="
%token TOK_HASHHASH "##"
%token TOK_HASHMINUSHASH "#-#"
%token TOK_HASHEQUALHASH "#=#"
%token TOK_COLONCOLON "::"
%token TOK_COLONEQUAL ":="
%token TOK_COLONSLASH ":/"
%token TOK_EQUALEQUALQUESTION "==?"
%token TOK_EXCLAMEQUALQUESTION "!=?"
%token TOK_LSQASTERIC "[*"
%token TOK_LSQPLUS "[+"
%token TOK_LSQEQUAL "[="
%token TOK_LSQMINUSGREATER "[->"
/* System Verilog Keywords */
%token TOK_ACCEPT_ON "accept_on"
%token TOK_ALIAS "alias"
%token TOK_ALWAYS_COMB "always_comb"
%token TOK_ALWAYS_FF "always_ff"
%token TOK_ALWAYS_LATCH "always_latch"
%token TOK_ASSERT "assert"
%token TOK_ASSUME "assume"
%token TOK_BEFORE "before"
%token TOK_BIND "bind"
%token TOK_BINS "bins"
%token TOK_BINSOF "binsof"
%token TOK_BIT "bit"
%token TOK_BREAK "break"
%token TOK_BYTE "byte"
%token TOK_CHANDLE "chandle"
%token TOK_CHECKER "checker"
%token TOK_CELL "cell"
%token TOK_CLASS "class"
%token TOK_CLOCKING "clocking"
%token TOK_CONFIG "config"
%token TOK_CONST "const"
%token TOK_CONSTRAINT "constraint"
%token TOK_CONTEXT "context"
%token TOK_CONTINUE "continue"
%token TOK_COVER "cover"
%token TOK_COVERGROUP "covergroup"
%token TOK_COVERPOINT "coverpoint"
%token TOK_CROSS "cross"
%token TOK_DESIGN "design"
%token TOK_DIST "dist"
%token TOK_DO "do"
%token TOK_ENDCHECKER "endchecker"
%token TOK_ENDCLASS "endclass"
%token TOK_ENDCLOCKING "endclocking"
%token TOK_ENDCONFIG "endconfig"
%token TOK_ENDGROUP "endgroup"
%token TOK_ENDINTERFACE "endinterface"
%token TOK_ENDPACKAGE "endpackage"
%token TOK_ENDPROGRAM "endprogram"
%token TOK_ENDPROPERTY "endproperty"
%token TOK_ENDSEQUENCE "endsequence"
%token TOK_ENUM "enum"
%token TOK_EVENTUALLY "eventually"
%token TOK_EXPECT "expect"
%token TOK_EXPORT "export"
%token TOK_EXTENDS "extends"
%token TOK_EXTERN "extern"
%token TOK_FINAL "final"
%token TOK_FIRST_MATCH "first_match"
%token TOK_FOREACH "foreach"
%token TOK_FORKJOIN "forkjoin"
%token TOK_GLOBAL "global"
%token TOK_IFF "iff"
%token TOK_IGNORE_BINS "ignore_bins"
%token TOK_ILLEGAL_BINS "illegal_bins"
%token TOK_IMPLEMENTS "implements"
%token TOK_IMPLIES "implies"
%token TOK_IMPORT "import"
%token TOK_INSIDE "inside"
%token TOK_INT "int"
%token TOK_INTERCONNECT "interconnect"
%token TOK_INTERFACE "interface"
%token TOK_INTERSECT "intersect"
%token TOK_JOIN_ANY "join_any"
%token TOK_JOIN_NONE "join_none"
%token TOK_LET "let"
%token TOK_LOCAL "local"
%token TOK_LOGIC "logic"
%token TOK_LONGINT "longint"
%token TOK_MATCHES "matches"
%token TOK_MODPORT "modport"
%token TOK_NETTYPE "nettype"
%token TOK_NEW "new"
%token TOK_NEXTTIME "nexttime"
%token TOK_NULL "null"
%token TOK_PACKAGE "package"
%token TOK_PACKED "packed"
%token TOK_PRIORITY "priority"
%token TOK_PROGRAM "program"
%token TOK_PROPERTY "property"
%token TOK_PROTECTED "protected"
%token TOK_PURE "pure"
%token TOK_RAND "rand"
%token TOK_RANDC "randc"
%token TOK_RANDCASE "randcase"
%token TOK_RANDSEQUENCE "randsequence"
%token TOK_REF "ref"
%token TOK_REJECT_ON "reject_on"
%token TOK_RESTRICT "restrict"
%token TOK_RETURN "return"
%token TOK_S_ALWAYS "s_always"
%token TOK_S_EVENTUALLY "s_eventually"
%token TOK_S_NEXTTIME "s_nexttime"
%token TOK_S_UNTIL "s_until"
%token TOK_S_UNTIL_WITH "s_until_with"
%token TOK_SEQUENCE "sequence"
%token TOK_SHORTINT "shortint"
%token TOK_SHORTREAL "shortreal"
%token TOK_SHOWCANCELLED "showcancelled"
%token TOK_SOFT "soft"
%token TOK_SOLVE "solve"
%token TOK_STATIC "static"
%token TOK_STRING "string"
%token TOK_STRONG "strong"
%token TOK_STRUCT "struct"
%token TOK_SUPER "super"
%token TOK_SYNC_ACCEPT_ON "sync_accept_on"
%token TOK_SYNC_REJECT_ON "sync_reject_on"
%token TOK_TAGGED "tagged"
%token TOK_THIS "this"
%token TOK_THROUGHOUT "throughout"
%token TOK_TIMEPRECISION "timeprecision"
%token TOK_TIMEUNIT "timeunit"
%token TOK_TYPE "type"
%token TOK_TYPEDEF "typedef"
%token TOK_UNION "union"
%token TOK_UNIQUE "unique"
%token TOK_UNIQUE0 "unique0"
%token TOK_UNTIL "until"
%token TOK_UNTIL_WITH "until_with"
%token TOK_UNTYPED "untyped"
%token TOK_VAR "var"
%token TOK_VIRTUAL "virtual"
%token TOK_VOID "void"
%token TOK_WAIT_ORDER "wait_order"
%token TOK_WEAK "weak"
%token TOK_WILDCARD "wildcard"
%token TOK_WITH "with"
%token TOK_WITHIN "within"
/* Others */
%token TOK_ENDOFFILE
%token TOK_NON_TYPE_IDENTIFIER
%token TOK_TYPE_IDENTIFIER
%token TOK_NUMBER // number, any base
%token TOK_TIME_LITERAL // number followed by time unit
%token TOK_QSTRING // quoted string
%token TOK_SYSIDENT // system task or function enable
%token TOK_SCANNER_ERROR
/* VL2SMV */
%token TOK_USING "using"
%token TOK_PROVE "prove"
// Precedence of System Verilog Assertions Operators,
// following System Verilog 1800-2017 Table 16-3.
// Bison expects these in order of increasing precedence,
// whereas the table gives them in decreasing order.
// The precendence of the assertion operators is lower than
// those in Table 11-2.
//
// SEQUENCE_TO_PROPERTY is an artificial token to give
// the right precedence to the conversion of a sequence_expr
// to a property_expr.
%nonassoc "property_expr_abort" // accept_on, reject_on, ...
%nonassoc "property_expr_clocking_event" // @(...) property_expr
%nonassoc "always" "s_always" "eventually" "s_eventually"
%nonassoc "accept_on" "reject_on"
%nonassoc "sync_accept_on" "sync_reject_on"
%right "|->" "|=>" "#-#" "#=#"
%nonassoc "until" "s_until" "until_with" "s_until_with" "implies"
%right "iff"
%left "or"
%left "and"
%nonassoc SEQUENCE_TO_PROPERTY
%nonassoc "not" "nexttime" "s_nexttime"
%left "intersect"
%left "within"
%right "throughout"
%left "##"
%nonassoc "[*" "[=" "[->"
// Precendence of Verilog operators,
// following System Verilog 1800-2017 Table 11-2.
// Bison expects these in order of increasing precedence,
// whereas the table gives them in decreasing order.
%right "->" "<->"
%right "?" ":"
%left "||"
%left "&&"
%left "|"
%left "^" "^~" "~^"
%left "&"
%left "==" "!=" "===" "!==" "==?" "!=?"
%left "<" "<=" ">" ">=" "inside" "dist"
%left "<<" ">>" "<<<" ">>>"
%left "+" "-"
%left "*" "/" "%"
%left "**"
%nonassoc UNARY_PLUS UNARY_MINUS "!" "~" "&~" "++" "--"
// Statements
%nonassoc LT_TOK_ELSE
%nonassoc TOK_ELSE
%%
/* Starting point */
grammar: TOK_PARSE_LANGUAGE { /*yydebug=1;*/ } source_text
| TOK_PARSE_EXPRESSION expression
{ PARSER.parse_tree.expr.swap(stack_expr($2)); }
| TOK_PARSE_TYPE data_type_or_implicit
{ PARSER.parse_tree.expr.swap(stack_expr($2)); }
;
// System Verilog standard 1800-2017
// A.1.2 SystemVerilog source text
source_text: description_brace;
description_brace:
/* Optional */
| description_brace description
;
description:
module_declaration
{ PARSER.parse_tree.add_item(stack_expr($1)); }
| udp_declaration
{ PARSER.parse_tree.add_item(stack_expr($1)); }
| interface_declaration
{ PARSER.parse_tree.add_item(stack_expr($1)); }
| program_declaration
{ PARSER.parse_tree.add_item(stack_expr($1)); }
| package_declaration
{ PARSER.parse_tree.add_item(stack_expr($1)); }
| attribute_instance_brace package_item
{ add_attributes($2, $1);
PARSER.parse_tree.add_item(stack_expr($2)); }
| attribute_instance_brace bind_directive
| config_declaration
;
// This deviates from the IEEE 1800-2017 grammar
// to allow the module scope to be opened.
module_identifier_with_scope:
module_identifier
{
$$ = $1;
push_scope(stack_expr($1).id(), ".");
}
;
module_nonansi_header:
attribute_instance_brace
module_keyword
module_identifier_with_scope
package_import_declaration_brace
parameter_port_list_opt
list_of_ports_opt ';'
{
init($$); stack_expr($$).operands().resize(5);
stack_expr($$).operands()[0].swap(stack_expr($1));
stack_expr($$).operands()[1].swap(stack_expr($2));
stack_expr($$).operands()[2].swap(stack_expr($3));
stack_expr($$).operands()[3].swap(stack_expr($5));
stack_expr($$).operands()[4].swap(stack_expr($6));
}
;
module_ansi_header:
attribute_instance_brace
module_keyword
module_identifier_with_scope
package_import_declaration_brace
parameter_port_list_opt
list_of_port_declarations ';'
{
init($$); stack_expr($$).operands().resize(5);
stack_expr($$).operands()[0].swap(stack_expr($1));
stack_expr($$).operands()[1].swap(stack_expr($2));
stack_expr($$).operands()[2].swap(stack_expr($3));
stack_expr($$).operands()[3].swap(stack_expr($5));
stack_expr($$).operands()[4].swap(stack_expr($6));
}
;
module_declaration:
module_nonansi_header module_item_brace TOK_ENDMODULE endmodule_identifier_opt
{
init($$);
stack_expr($$) = PARSER.parse_tree.create_module(
stack_expr($1).operands()[0],
stack_expr($1).operands()[1],
stack_expr($1).operands()[2],
stack_expr($1).operands()[3],
stack_expr($1).operands()[4],
stack_expr($2));
// close the module scope
pop_scope();
}
| module_ansi_header module_item_brace TOK_ENDMODULE endmodule_identifier_opt
{
init($$);
stack_expr($$) = PARSER.parse_tree.create_module(
stack_expr($1).operands()[0],
stack_expr($1).operands()[1],
stack_expr($1).operands()[2],
stack_expr($1).operands()[3],
stack_expr($1).operands()[4],
stack_expr($2));
// close the module scope
pop_scope();
}
| TOK_EXTERN module_nonansi_header
/* ignored for now */
{ init($$); }
| TOK_EXTERN module_ansi_header
/* ignored for now */
{ init($$); }
;
module_keyword:
TOK_MODULE { init($$, ID_module); }
| TOK_MACROMODULE { init($$, ID_macromodule); }
;
interface_declaration:
interface_nonansi_header
timeunits_declaration_opt
interface_item_brace
TOK_ENDINTERFACE
{ $$ = $1; }
;
interface_nonansi_header:
attribute_instance_brace
TOK_INTERFACE
lifetime_opt
interface_identifier
{
init($$, ID_verilog_interface);
stack_expr($$).set(ID_base_name, stack_expr($4).id());
}
package_import_declaration_brace
parameter_port_list_opt
list_of_ports_opt
';'
{
$$ = $5;
}
;
program_declaration:
TOK_PROGRAM TOK_ENDPROGRAM
;
checker_declaration:
TOK_CHECKER { init($$); } checker_identifier
checker_port_list_paren_opt ';'
checker_or_generate_item_brace
TOK_ENDCHECKER
{
init($$);
irept attributes;
exprt parameter_port_list;
stack_expr($$) = verilog_parse_treet::create_module(
attributes, // attributes,
stack_expr($2), // module_keyword
stack_expr($3), // name
parameter_port_list, // parameter_port_list
stack_expr($4), // ports
stack_expr($6) // module_items
);
stack_expr($$).id(ID_verilog_checker);
}
;
checker_port_list_paren_opt:
/* Optional */
{ init($$); }
| '(' checker_port_list_opt ')'
{ $$ = $2; }
;
checker_port_list_opt:
/* Optional */
{ init($$); }
| checker_port_list
;
checker_port_list:
checker_port_item
{ init($$); mts($$, $1); }
| checker_port_list checker_port_item
{ $$ = $1; mts($$, $2); }
;
checker_port_item:
attribute_instance_brace
checker_port_direction_opt
property_formal_type
formal_port_identifier
variable_dimension_brace
{ init($$, ID_decl);
stack_expr($$).set(ID_class, stack_expr($2).id());
addswap($$, ID_type, $3);
mto($$, $4); /* declarator */
}
;
checker_port_direction_opt:
/* Optional */
{ init($$); }
| TOK_INPUT
{ init($$, ID_input); }
| TOK_OUTPUT
{ init($$, ID_output); }
;
class_declaration:
TOK_CLASS class_identifier
';'
{
init($$, ID_verilog_class);
stack_expr($$).set(ID_base_name, stack_expr($2).id());
push_scope(stack_expr($2).id(), "::");
}
class_item_brace
TOK_ENDCLASS
{
$$ = $4;
pop_scope();
}
;
package_declaration:
attribute_instance_brace TOK_PACKAGE
{ init($$, ID_verilog_package); }
lifetime_opt
package_identifier ';'
{
push_scope(stack_expr($5).id(), "::");
}
timeunits_declaration_opt
package_item_brace
TOK_ENDPACKAGE endpackage_identifier_opt
{
pop_scope();
$$ = $3;
addswap($$, ID_module_items, $9);
stack_expr($$).set(ID_base_name, stack_expr($5).id());
}
;
endpackage_identifier_opt:
/* Optional */
| TOK_COLON package_identifier
;
timeunits_declaration_opt:
/* Optional */
;
// System Verilog standard 1800-2017
// A.1.3 Module parameters and ports
// This deviates from the grammar in the standard to address an
// ambiguity between the comma in list_of_param_assignments
// and the comma in parameter_port_list. The productions
// allowed by list_of_param_assignments are folded into
// parameter_port_declaration.
parameter_port_list_opt:
/* Optional */
{ init($$); }
| '#' '(' parameter_port_declaration_brace ')'
{ $$ = $3; }
| '#' '(' ')'
{ init($$); }
;
list_of_ports_opt:
/* Optional */
{ make_nil($$); }
| list_of_ports
;
list_of_ports: '(' port_brace ')' { $$ = $2; }
;
list_of_port_declarations: '(' ansi_port_declaration_brace ')' { $$=$2; }
;
ansi_port_declaration_brace:
attribute_instance_brace ansi_port_declaration
{ init($$); mts($$, $2); }
| ansi_port_declaration_brace ',' attribute_instance_brace ansi_port_declaration
{ $$=$1; mts($$, $4); }
// append to last one -- required to make
// the grammar LR1
| ansi_port_declaration_brace ',' port_identifier
{ $$=$1;
exprt decl(ID_decl);
decl.add_to_operands(std::move(stack_expr($3)));
// grab the type and class from previous!
const irept &prev=stack_expr($$).get_sub().back();
decl.set(ID_type, prev.find(ID_type));
decl.set(ID_class, prev.find(ID_class));
stack_expr($$).move_to_sub(decl);
}
;
port_declaration:
attribute_instance_brace inout_declaration
{ add_attributes($2, $1); $$=$2; }
| attribute_instance_brace input_declaration
{ add_attributes($2, $1); $$=$2; }
| attribute_instance_brace output_declaration
{ add_attributes($2, $1); $$=$2; }
;
ansi_port_initializer_opt:
/* Optional */
{ init($$, ID_nil); }
| '=' expression
{ $$ = $2; }
;
ansi_port_declaration:
net_port_header port_identifier unpacked_dimension_brace ansi_port_initializer_opt
{ init($$, ID_decl);
stack_expr($$).set(ID_class, to_unary_expr(stack_expr($1)).op().id());
// The data_type goes onto the declaration,
// and the unpacked_array_type goes onto the declarator.
stack_expr($$).type() = std::move(stack_expr($1).type());
addswap($2, ID_type, $3);
mto($$, $2); /* declarator */ }
| variable_port_header port_identifier unpacked_dimension_brace ansi_port_initializer_opt
{ init($$, ID_decl);
if(to_unary_expr(stack_expr($1)).op().id() == ID_output)
stack_expr($$).set(ID_class, ID_output_register);
else
stack_expr($$).set(ID_class, to_unary_expr(stack_expr($1)).op().id());
// The data_type goes onto the declaration,
// and the unpacked_array_type goes onto the declarator.
stack_expr($$).type() = std::move(stack_expr($1).type());
addswap($2, ID_type, $3);
mto($$, $2); /* declarator */ }
;
net_port_header:
port_direction net_port_type
{ init($$);
mto($$, $1);
addswap($$, ID_type, $2);
}
;
variable_port_header:
port_direction var_data_type
{ init($$);
mto($$, $1);
addswap($$, ID_type, $2);
}
;
port_direction:
TOK_INPUT
{ init($$, ID_input); }
| TOK_OUTPUT
{ init($$, ID_output); }
| TOK_INOUT
{ init($$, ID_inout); }
| TOK_REF
{ init($$, ID_verilog_ref); }
;
// System Verilog standard 1800-2017
// A.1.4 Module items
module_common_item:
module_or_generate_item_declaration
| assertion_item
| bind_directive
| continuous_assign
| initial_construct
| final_construct
| always_construct
| loop_generate_construct
| conditional_generate_construct
;
module_item:
port_declaration ';'
| non_port_module_item
;
module_item_brace:
/* Optional */
{ init($$); }