Qucs-core
0.0.19
|
00001 /* -*-c++-*- */ 00002 00003 %{ 00004 /* 00005 * parse_vcd.y - parser for a VCD data file 00006 * 00007 * Copyright (C) 2005 Raimund Jacob <raimi@lkcc.org> 00008 * Copyright (C) 2006, 2008 Stefan Jahn <stefan@lkcc.org> 00009 * 00010 * This is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2, or (at your option) 00013 * any later version. 00014 * 00015 * This software is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this package; see the file COPYING. If not, write to 00022 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 00023 * Boston, MA 02110-1301, USA. 00024 * 00025 * $Id$ 00026 * 00027 */ 00028 00029 #if HAVE_CONFIG_H 00030 # include <config.h> 00031 #endif 00032 00033 #include <stdio.h> 00034 #include <stdlib.h> 00035 #include <string.h> 00036 #include <ctype.h> 00037 00038 #define YYERROR_VERBOSE 42 00039 #define YYDEBUG 1 00040 #define YYMAXDEPTH 10000000 00041 00042 #include "check_vcd.h" 00043 00044 %} 00045 00046 %name-prefix "vcd_" 00047 00048 %token t_END 00049 %token t_COMMENT 00050 %token t_DATE 00051 %token t_ENDDEFINITIONS 00052 %token t_SCOPE 00053 %token t_TIMESCALE 00054 %token t_UPSCOPE 00055 %token t_VAR 00056 %token t_VERSION 00057 %token t_DUMPALL 00058 %token t_DUMPOFF 00059 %token t_DUMPON 00060 %token t_DUMPVARS 00061 00062 %token s_MODULE s_TASK s_FUNCTION s_FORK s_BEGIN 00063 %token ONE B Z ZERO HASHMARK X R TEN HUNDRET 00064 00065 %token PICO MICRO NANO FEMTO SECOND MILLI 00066 00067 %token EVENT INTEGER PARAMETER REAL REG SUPPLY0 SUPPLY1 TIME TRI TRIAND 00068 %token TRIOR TRIREG TRI0 TRI1 WAND WIRE WOR 00069 00070 %token Real 00071 %token Binary 00072 %token PositiveInteger 00073 %token PositiveHugeInteger 00074 %token Identifier /* proper identifiers */ 00075 %token IdentifierCode /* shortcuts used in the dump */ 00076 %token Reference 00077 %token InvalidCharacter 00078 00079 %union { 00080 char * ident; 00081 char * value; 00082 int integer; 00083 double real; 00084 enum vcd_vartypes vtype; 00085 enum vcd_scopes stype; 00086 struct vcd_vardef * vardef; 00087 struct vcd_change * change; 00088 struct vcd_scope * scope; 00089 struct vcd_changeset * changeset; 00090 struct vcd_range * range; 00091 } 00092 00093 %type <ident> Identifier IdentifierCode Reference 00094 %type <value> Value ZERO ONE Z X Binary Real 00095 %type <integer> Size PositiveInteger TimeScale 00096 %type <real> TimeUnit SimulationTime PositiveHugeInteger 00097 %type <change> ScalarValueChange VectorValueChange ValueChangeList ValueChange 00098 %type <changeset> ValueChangeset 00099 %type <scope> ScopeDeclaration 00100 %type <range> BitSelect 00101 %type <vardef> VarDeclaration 00102 %type <vtype> VarType 00103 %type <stype> ScopeType 00104 00105 %% 00106 00107 ValueChangeDumpDefinitions: 00108 DeclarationList SimulationCommandList 00109 ; 00110 00111 DeclarationList: /* empty */ 00112 | Declaration DeclarationList 00113 ; 00114 00115 Declaration: 00116 t_COMMENT t_END 00117 | t_DATE t_END 00118 | t_ENDDEFINITIONS t_END 00119 | t_SCOPE ScopeDeclaration t_END { 00120 if (!vcd->scopes) { 00121 /* no scope defined yet */ 00122 vcd->scopes = (struct vcd_scope *) 00123 calloc (1, sizeof (struct vcd_scope)); 00124 vcd->scopes->ident = strdup (VCD_NOSCOPE); 00125 vcd->scopes->scopes = $2; 00126 $2->parent = vcd->scopes; 00127 } else { 00128 /* concatenate scope definitions */ 00129 $2->next = vcd->currentscope->scopes; 00130 vcd->currentscope->scopes = $2; 00131 $2->parent = vcd->currentscope; 00132 } 00133 vcd->currentscope = $2; 00134 } 00135 | t_TIMESCALE TimeScaleDeclaration t_END 00136 | t_UPSCOPE t_END { 00137 if (vcd->currentscope->parent) { 00138 /* up one scope */ 00139 vcd->currentscope = vcd->currentscope->parent; 00140 } else { 00141 fprintf (stderr, "vcd notice, unnecessary $upscope in line %d\n", 00142 vcd_lineno); 00143 } 00144 } 00145 | t_VERSION t_END 00146 | t_VAR VarDeclaration t_END { 00147 if (!vcd->scopes) { 00148 /* no scope defined yet */ 00149 vcd->scopes = (struct vcd_scope *) 00150 calloc (1, sizeof (struct vcd_scope)); 00151 vcd->scopes->ident = strdup (VCD_NOSCOPE); 00152 vcd->currentscope = vcd->scopes; 00153 } 00154 /* concatenate variable definitions */ 00155 $2->scope = vcd->currentscope; 00156 $2->next = vcd->currentscope->vardefs; 00157 vcd->currentscope->vardefs = $2; 00158 } 00159 ; 00160 00161 ScopeDeclaration: 00162 ScopeType Identifier { 00163 $$ = (struct vcd_scope *) calloc (1, sizeof (struct vcd_scope)); 00164 $$->type = $1; 00165 $$->ident = $2; 00166 } 00167 ; 00168 00169 ScopeType: 00170 s_MODULE { $$ = SCOPE_MODULE; } 00171 | s_TASK { $$ = SCOPE_TASK; } 00172 | s_FUNCTION { $$ = SCOPE_FUNCTION; } 00173 | s_BEGIN { $$ = SCOPE_BEGIN; } 00174 | s_FORK { $$ = SCOPE_FORK; } 00175 ; 00176 00177 TimeScaleDeclaration: 00178 TimeScale TimeUnit { 00179 vcd->t = $1; 00180 vcd->scale = $2; 00181 } 00182 ; 00183 00184 TimeScale: 00185 ONE { $$ = 1; } 00186 | TEN { $$ = 10; } 00187 | HUNDRET { $$ = 100; } 00188 ; 00189 00190 TimeUnit: 00191 SECOND { $$ = 1; } 00192 | MILLI { $$ = 1e-3; } 00193 | MICRO { $$ = 1e-6; } 00194 | NANO { $$ = 1e-9; } 00195 | PICO { $$ = 1e-12; } 00196 | FEMTO { $$ = 1e-15; } 00197 ; 00198 00199 VarDeclaration: 00200 VarType Size IdentifierCode Reference BitSelect { 00201 $$ = (struct vcd_vardef *) calloc (1, sizeof (struct vcd_vardef)); 00202 $$->type = $1; 00203 $$->size = $2; 00204 $$->code = $3; 00205 $$->ident = $4; 00206 $$->range = $5; 00207 } 00208 ; 00209 00210 BitSelect: /* nothing */ { $$ = NULL; } 00211 | '[' PositiveInteger ']' { 00212 $$ = (struct vcd_range *) calloc (1, sizeof (struct vcd_range)); 00213 $$->l = -1; 00214 $$->h = $2; 00215 } 00216 | '[' PositiveInteger ':' PositiveInteger ']' { 00217 $$ = (struct vcd_range *) calloc (1, sizeof (struct vcd_range)); 00218 $$->l = $2; 00219 $$->h = $4; 00220 } 00221 | '(' PositiveInteger ')' { 00222 $$ = (struct vcd_range *) calloc (1, sizeof (struct vcd_range)); 00223 $$->l = $2; 00224 $$->h = -1; 00225 } 00226 ; 00227 00228 VarType: 00229 EVENT { $$ = VAR_EVENT; 00230 /* a special type to synchronize different statement blocks */ } 00231 | INTEGER { $$ = VAR_INTEGER; 00232 /* signed 32-bit variable */ } 00233 | PARAMETER { $$ = VAR_PARAMETER; 00234 /* a named constant - the default value of a parameter can be 00235 overwritten, when declaring an instance of the associated module */ } 00236 | REAL { $$ = VAR_REAL; 00237 /* double-precision floating point */ } 00238 | REG { $$ = VAR_REG; 00239 /* unsigned variable of any bit size */ } 00240 | SUPPLY0 { $$ = VAR_SUPPLY0; 00241 /* constant logic 0 (supply strength) */ } 00242 | SUPPLY1 { $$ = VAR_SUPPLY1; 00243 /* constant logic 1 (supply strength) */ } 00244 | TIME { $$ = VAR_TIME; 00245 /* unsigned 64-bit variable */ } 00246 | TRI { $$ = VAR_TRI; 00247 /* simple interconnecting wire */ } 00248 | TRIAND { $$ = VAR_TRIAND; 00249 /* wired outputs AND together */ } 00250 | TRIOR { $$ = VAR_TRIOR; 00251 /* wired outputs OR together */ } 00252 | TRIREG { $$ = VAR_TRIREG; 00253 /* stores last value when tri-stated (capacitance strength) */ } 00254 | TRI0 { $$ = VAR_TRI0; 00255 /* pulls down when tri-stated */ } 00256 | TRI1 { $$ = VAR_TRI1; 00257 /* pulls up when tri-stated */ } 00258 | WAND { $$ = VAR_WAND; 00259 /* wired outputs AND together */ } 00260 | WIRE { $$ = VAR_WIRE; 00261 /* simple interconnecting wire */ } 00262 | WOR { $$ = VAR_WOR; 00263 /* wired outputs OR together */ } 00264 ; 00265 00266 Size: 00267 PositiveInteger 00268 ; 00269 00270 SimulationCommandList: /* empty */ 00271 | SimulationCommand SimulationCommandList 00272 ; 00273 00274 SimulationCommand: 00275 t_DUMPALL ValueChangeList t_END /* probably unsupported */ 00276 | t_DUMPOFF ValueChangeList t_END /* probably unsupported */ 00277 | t_DUMPON ValueChangeList t_END /* probably unsupported */ 00278 | t_DUMPVARS ValueChangeList t_END { 00279 vcd->changesets->changes = $2; 00280 } 00281 | ValueChangeset { 00282 $1->next = vcd->changesets; 00283 vcd->changesets = $1; 00284 } 00285 ; 00286 00287 ValueChangeset: 00288 SimulationTime ValueChangeList { 00289 $$ = (struct vcd_changeset *) calloc (1, sizeof (struct vcd_changeset)); 00290 $$->t = $1; 00291 $$->changes = $2; 00292 } 00293 ; 00294 00295 SimulationTime: 00296 HASHMARK PositiveHugeInteger { 00297 $$ = $2; 00298 } 00299 ; 00300 00301 ValueChangeList: /* nothing */ { $$ = NULL; } 00302 | ValueChange ValueChangeList { 00303 $1->next = $2; 00304 } 00305 ; 00306 00307 ValueChange: 00308 ScalarValueChange 00309 | VectorValueChange 00310 ; 00311 00312 ScalarValueChange: 00313 Value IdentifierCode { 00314 $$ = (struct vcd_change *) calloc (1, sizeof (struct vcd_change)); 00315 $$->value = $1; 00316 $$->code = $2; 00317 } 00318 ; 00319 00320 Value: 00321 ZERO /* low level */ 00322 | ONE /* high level */ 00323 | X /* undefined/error */ 00324 | Z /* high impedance */ 00325 ; 00326 00327 VectorValueChange: 00328 'B' Binary IdentifierCode { 00329 $$ = (struct vcd_change *) calloc (1, sizeof (struct vcd_change)); 00330 $$->value = $2; 00331 $$->code = $3; 00332 } 00333 | 'R' Real IdentifierCode { 00334 $$ = (struct vcd_change *) calloc (1, sizeof (struct vcd_change)); 00335 $$->value = $2; 00336 $$->code = $3; 00337 $$->isreal = 1; 00338 } 00339 ; 00340 00341 00342 %% 00343 00344 int vcd_error (const char * error) { 00345 fprintf (stderr, "line %d: %s\n", vcd_lineno, error); 00346 return 0; 00347 }