Qucs-core  0.0.19
parse_vcd.y
Go to the documentation of this file.
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 }