Qucs-core
0.0.19
|
00001 /* -*-c++-*- */ 00002 00003 %{ 00004 /* 00005 * parse_spice.y - parser for a Spice netlist 00006 * 00007 * Copyright (C) 2004, 2005, 2006, 2007, 2009 Stefan Jahn <stefan@lkcc.org> 00008 * 00009 * This is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2, or (at your option) 00012 * any later version. 00013 * 00014 * This software is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this package; see the file COPYING. If not, write to 00021 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 00022 * Boston, MA 02110-1301, USA. 00023 * 00024 * $Id$ 00025 * 00026 */ 00027 00028 #if HAVE_CONFIG_H 00029 # include <config.h> 00030 #endif 00031 00032 #include <stdio.h> 00033 #include <stdlib.h> 00034 #include <string.h> 00035 #include <ctype.h> 00036 00037 #if defined(_WIN32) & not defined(__MINGW32__) 00038 #define strcasecmp stricmp 00039 #endif 00040 00041 #define YYERROR_VERBOSE 42 00042 #define YYDEBUG 1 00043 #define YYMAXDEPTH 1000000 00044 00045 #include "check_spice.h" 00046 00047 // Converts the given string into upper case. 00048 static char * spice_toupper (char * str) { 00049 for (unsigned int i = 0; i < strlen (str); i++) { 00050 if (str[i] >= 'a' && str[i] <= 'z') str[i] = toupper (str[i]); 00051 } 00052 return str; 00053 } 00054 00055 // Creates a device instance. 00056 static struct definition_t * spice_create_device (char * instance) { 00057 struct definition_t * def = create_definition (); 00058 def->action = PROP_COMPONENT; 00059 def->instance = spice_toupper (instance); 00060 def->type = (char *) calloc (2, 1); 00061 def->type[0] = def->instance[0]; 00062 def->line = spice_lineno; 00063 return def; 00064 } 00065 00066 // Creates an action instance. 00067 static struct definition_t * spice_create_action (char * type, 00068 char * instance) { 00069 struct definition_t * def = create_definition (); 00070 def->action = PROP_ACTION; 00071 def->instance = spice_toupper (instance); 00072 def->type = spice_toupper (type); 00073 def->line = spice_lineno; 00074 return def; 00075 } 00076 00077 // Create a string value. 00078 static struct value_t * spice_create_str_value (char * value, int hint) { 00079 struct value_t * val = create_value (); 00080 val->ident = spice_toupper (value); 00081 val->hint |= hint; 00082 return val; 00083 } 00084 00085 // Create a real value. 00086 static struct value_t * spice_create_val_value (char * value, int hint) { 00087 struct value_t * val = create_value (); 00088 val->ident = value; 00089 val->value = strtod (value, NULL); 00090 val->hint |= hint; 00091 return val; 00092 } 00093 00094 // Create a key/value pair. 00095 static struct value_t * spice_create_par_value (char * key, char * value) { 00096 struct value_t * val = spice_create_str_value (key, HINT_PAIR); 00097 val->unit = value; 00098 return val; 00099 } 00100 00101 // Append a string value to the definition. 00102 static void spice_append_str_value (struct definition_t * def, 00103 char * value, int hint) { 00104 struct value_t * val = spice_create_str_value (value, hint); 00105 def->values = netlist_append_values (def->values, val); 00106 } 00107 00108 // Append a string value to the given values. 00109 static struct value_t * spice_append_str_values (struct value_t * values, 00110 char * value, int hint) { 00111 struct value_t * val = spice_create_str_value (value, hint); 00112 return netlist_append_values (values, val); 00113 } 00114 00115 // Append a real value to the definition. 00116 static void spice_append_val_value (struct definition_t * def, 00117 char * value, int hint) { 00118 struct value_t * val = spice_create_val_value (value, hint); 00119 def->values = netlist_append_values (def->values, val); 00120 } 00121 00122 // Append a real value to the given values. 00123 static struct value_t * spice_append_val_values (struct value_t * values, 00124 char * value, int hint) { 00125 struct value_t * val = spice_create_val_value (value, hint); 00126 return netlist_append_values (values, val); 00127 } 00128 00129 %} 00130 00131 %name-prefix "spice_" 00132 00133 %token TitleLine InvalidCharacter End Eol 00134 %token Identifier Digits Floats Nodes Options Function 00135 %token SUBCKT_Action ENDS_Action AC_Action OP_Action I_Source SAVE_Action 00136 %token RLC_Device L_Device K_Device IV_Source GE_Source FH_Source V_Source 00137 %token Diode_Device Bipolar_Device JFET_Device MOSFET_Device MESFET_Device 00138 %token MODEL_Action MODEL_Spec TRAN_Action PLOT_Action VoltFunc CurrFunc 00139 %token DC_Action PRINT_Action OPTIONS_Action WIDTH_Action NOISE_Action 00140 %token PZ_Action CurVol PoleZero ALL_Special X_Device O_Device ModelProps 00141 %token OFF_Special IC_Special SIM_Type TEMP_Special MOS_Special B_Source 00142 %token DISTO_Action INCLUDE_Action File BranchFunc NODESET_Action T_Device 00143 %token U_Device S_Device W_Device ON_Special TF_Action SENS_Action FOUR_Action 00144 %token OpFunc Behave TC_Special TEMP_Action 00145 00146 %union { 00147 char * ident; 00148 char * str; 00149 double d; 00150 struct definition_t * definition; 00151 struct definition_t * subcircuit; 00152 struct value_t * value; 00153 } 00154 00155 %type <str> TitleLine 00156 %type <definition> DefinitionLine BeginSub SubBody Subcircuit SubBodyLine 00157 00158 %type <value> NodeList PairList Expr DC_List ValueList ExprList PLOT_List 00159 %type <value> VOLTAGE_Output CURRENT_Output Output_Range PRINT_List 00160 %type <value> OPTIONS_List MODEL_List DEVICE_List_1 DEVICE_List_2 DEVICE_List_3 00161 %type <value> IC_Condition_1 IC_Condition_2 IC_Condition_3 NODESET_List 00162 %type <value> IC_Condition_4 SWITCH_State NodeValueList TC_Value_1 TC_Value_2 00163 %type <value> VSourceList 00164 00165 %type <ident> Identifier Nodes Function Value Floats Digits Node FH_Node 00166 %type <ident> RLC_Device K_Device L_Device IV_Source GE_Source FH_Source 00167 %type <ident> V_Source MODEL_Spec Diode_Device Bipolar_Device JFET_Device 00168 %type <ident> MOSFET_Device MESFET_Device TRAN_Action PLOT_Action MODEL_Action 00169 %type <ident> VoltFunc CurrFunc AC_Action DC_Action B_Source DISTO_Action 00170 %type <ident> PRINT_Action Options OPTIONS_Action WIDTH_Action INCLUDE_Action 00171 %type <ident> NOISE_Action PZ_Action CurVol PoleZero ALL_Special File 00172 %type <ident> X_Device SUBCKT_Action SubCkt_Ident O_Device MODEL_Ident 00173 %type <ident> ModelProps OP_Action I_Source IV_Reference SAVE_Action ON_Special 00174 %type <ident> IC_Special OFF_Special SIM_Type TEMP_Special MOS_Special 00175 %type <ident> BranchFunc NODESET_Action T_Device U_Device S_Device W_Device 00176 %type <ident> TF_Action SENS_Action FOUR_Action OpFunc TC_Special TEMP_Action 00177 %type <ident> Behave 00178 00179 %% 00180 00181 Input: 00182 InputList End { 00183 } 00184 | TitleLine InputList End { 00185 spice_title = $1; 00186 } 00187 | InputList { 00188 fprintf (stderr, "spice notice, no .END directive found, continuing\n"); 00189 } 00190 | TitleLine InputList { 00191 spice_title = $1; 00192 fprintf (stderr, "spice notice, no .END directive found, continuing\n"); 00193 } 00194 ; 00195 00196 InputList: /* nothing */ 00197 | InputLine InputList 00198 ; 00199 00200 InputLine: 00201 Subcircuit { 00202 /* chain definition root */ 00203 $1->next = definition_root; 00204 definition_root = $1; 00205 } 00206 | DefinitionLine { 00207 /* chain definition root */ 00208 if ($1) { 00209 $1->next = definition_root; 00210 definition_root = $1; 00211 } 00212 } 00213 | Eol { /* nothing to do here */ } 00214 ; 00215 00216 DefinitionLine: 00217 RLC_Device Node Node Value PairList Eol { 00218 /* R, L and C definitions */ 00219 $$ = spice_create_device ($1); 00220 spice_append_str_value ($$, $2, HINT_NODE); 00221 spice_append_str_value ($$, $3, HINT_NODE); 00222 spice_append_val_value ($$, $4, HINT_NUMBER); 00223 $$->values = netlist_append_values ($$->values, $5); 00224 } 00225 | RLC_Device Node Node Value MODEL_Ident PairList Eol { 00226 /* R, L and C definitions specified by a Model */ 00227 $$ = spice_create_device ($1); 00228 spice_append_str_value ($$, $2, HINT_NODE); 00229 spice_append_str_value ($$, $3, HINT_NODE); 00230 spice_append_val_value ($$, $4, HINT_NUMBER); 00231 spice_append_str_value ($$, $5, HINT_NAME); 00232 $$->values = netlist_append_values ($$->values, $6); 00233 } 00234 | RLC_Device Node Node MODEL_Ident Value Eol { 00235 /* R, L and C definitions specified by a Model, a variant */ 00236 $$ = spice_create_device ($1); 00237 spice_append_str_value ($$, $2, HINT_NODE); 00238 spice_append_str_value ($$, $3, HINT_NODE); 00239 spice_append_val_value ($$, $5, HINT_NUMBER); 00240 spice_append_str_value ($$, $4, HINT_NAME); 00241 } 00242 | RLC_Device Node Node MODEL_Ident PairList Eol { 00243 /* R definitions specified by a Model, yet another variant */ 00244 $$ = spice_create_device ($1); 00245 spice_append_str_value ($$, $2, HINT_NODE); 00246 spice_append_str_value ($$, $3, HINT_NODE); 00247 spice_append_str_value ($$, $4, HINT_NAME); 00248 $$->values = netlist_append_values ($$->values, $5); 00249 } 00250 | RLC_Device Node Node Value TC_Value_1 Eol { 00251 /* R definitions including TC1 */ 00252 $$ = spice_create_device ($1); 00253 spice_append_str_value ($$, $2, HINT_NODE); 00254 spice_append_str_value ($$, $3, HINT_NODE); 00255 spice_append_val_value ($$, $4, HINT_NUMBER); 00256 $$->values = netlist_append_values ($$->values, $5); 00257 } 00258 | RLC_Device Node Node Value TC_Value_2 Eol { 00259 /* R definitions including TC1/TC2 */ 00260 $$ = spice_create_device ($1); 00261 spice_append_str_value ($$, $2, HINT_NODE); 00262 spice_append_str_value ($$, $3, HINT_NODE); 00263 spice_append_val_value ($$, $4, HINT_NUMBER); 00264 $$->values = netlist_append_values ($$->values, $5); 00265 } 00266 | RLC_Device Node Node Value Behave NodeValueList Eol { 00267 /* non-linear C and L poly definitions */ 00268 $$ = spice_create_device ($1); 00269 spice_append_str_value ($$, $2, HINT_NODE); 00270 spice_append_str_value ($$, $3, HINT_NODE); 00271 spice_append_val_value ($$, $4, HINT_NUMBER); 00272 spice_append_str_value ($$, $5, HINT_NAME); 00273 $$->values = netlist_append_values ($$->values, $6); 00274 } 00275 | K_Device L_Device L_Device Value Eol { 00276 /* Mutual inductors */ 00277 $$ = spice_create_device ($1); 00278 spice_append_str_value ($$, $2, HINT_NAME); 00279 spice_append_str_value ($$, $3, HINT_NAME); 00280 spice_append_val_value ($$, $4, HINT_NUMBER); 00281 } 00282 | IV_Source Node Node ExprList Eol { 00283 /* independent current/voltage sources */ 00284 $$ = spice_create_device ($1); 00285 spice_append_str_value ($$, $2, HINT_NODE); 00286 spice_append_str_value ($$, $3, HINT_NODE); 00287 $$->values = netlist_append_values ($$->values, $4); 00288 } 00289 | IV_Source Node Node Value ExprList Eol { 00290 /* independent current/voltage sources given the value */ 00291 $$ = spice_create_device ($1); 00292 spice_append_str_value ($$, $2, HINT_NODE); 00293 spice_append_str_value ($$, $3, HINT_NODE); 00294 spice_append_val_value ($$, $4, HINT_NUMBER); 00295 $$->values = netlist_append_values ($$->values, $5); 00296 } 00297 | GE_Source Node Node Behave Digits NodeValueList Eol { 00298 /* voltage controlled source POLY */ 00299 if (!strcasecmp ($4, "POLY")) { 00300 $$ = spice_create_device ($1); 00301 spice_append_str_value ($$, $2, HINT_NODE); 00302 spice_append_str_value ($$, $3, HINT_NODE); 00303 spice_append_str_value ($$, $4, HINT_NAME); 00304 spice_append_val_value ($$, $5, HINT_NUMBER); 00305 $$->values = netlist_append_values ($$->values, $6); 00306 } 00307 else { 00308 fprintf (stderr, "spice notice, behavioural %s source ignored\n", $1); 00309 $$ = NULL; 00310 } 00311 } 00312 | GE_Source Node Node Behave Eol { 00313 /* voltage controlled sources OTHER behavioural */ 00314 fprintf (stderr, "spice notice, behavioural %s source ignored\n", $1); 00315 $$ = NULL; 00316 } 00317 | GE_Source Node Node Node Node Value Eol { 00318 /* voltage controlled sources */ 00319 $$ = spice_create_device ($1); 00320 spice_append_str_value ($$, $2, HINT_NODE); 00321 spice_append_str_value ($$, $3, HINT_NODE); 00322 spice_append_str_value ($$, $4, HINT_NODE); 00323 spice_append_str_value ($$, $5, HINT_NODE); 00324 spice_append_val_value ($$, $6, HINT_NUMBER); 00325 } 00326 | FH_Source FH_Node FH_Node Behave Digits VSourceList NodeValueList Eol { 00327 /* current controlled source POLY */ 00328 if (!strcasecmp ($4, "POLY")) { 00329 $$ = spice_create_device ($1); 00330 spice_append_str_value ($$, $2, HINT_NODE); 00331 spice_append_str_value ($$, $3, HINT_NODE); 00332 spice_append_str_value ($$, $4, HINT_NAME); 00333 spice_append_val_value ($$, $5, HINT_NUMBER); 00334 $$->values = netlist_append_values ($$->values, $6); 00335 $$->values = netlist_append_values ($$->values, $7); 00336 } 00337 else { 00338 fprintf (stderr, "spice notice, behavioural %s source ignored\n", $1); 00339 $$ = NULL; 00340 } 00341 } 00342 | FH_Source FH_Node FH_Node Behave Eol { 00343 /* current controlled sources OTHER behavioural */ 00344 fprintf (stderr, "spice notice, behavioural %s source ignored\n", $1); 00345 $$ = NULL; 00346 } 00347 | FH_Source FH_Node FH_Node V_Source Value Eol { 00348 /* current controlled sources */ 00349 $$ = spice_create_device ($1); 00350 spice_append_str_value ($$, $2, HINT_NODE); 00351 spice_append_str_value ($$, $3, HINT_NODE); 00352 spice_append_str_value ($$, $4, HINT_NAME); 00353 spice_append_val_value ($$, $5, HINT_NUMBER); 00354 } 00355 | MODEL_Action MODEL_Ident MODEL_Spec MODEL_List Eol { 00356 /* device specification */ 00357 $$ = spice_create_action ($1, $2); 00358 spice_append_str_value ($$, $3, HINT_NAME | HINT_MSTART); 00359 spice_add_last_hint ($4, HINT_MSTOP); 00360 $$->values = netlist_append_values ($$->values, $4); 00361 } 00362 | Diode_Device Node Node MODEL_Ident DEVICE_List_1 { 00363 /* diode */ 00364 $$ = spice_create_device ($1); 00365 spice_append_str_value ($$, $2, HINT_NODE); 00366 spice_append_str_value ($$, $3, HINT_NODE); 00367 spice_append_str_value ($$, $4, HINT_NAME); 00368 $$->values = netlist_append_values ($$->values, $5); 00369 } 00370 | JFET_Device Node Node Node MODEL_Ident DEVICE_List_2 { 00371 /* JFET */ 00372 $$ = spice_create_device ($1); 00373 spice_append_str_value ($$, $2, HINT_NODE); 00374 spice_append_str_value ($$, $3, HINT_NODE); 00375 spice_append_str_value ($$, $4, HINT_NODE); 00376 spice_append_str_value ($$, $5, HINT_NAME); 00377 $$->values = netlist_append_values ($$->values, $6); 00378 } 00379 | Bipolar_Device Node Node Node MODEL_Ident DEVICE_List_2 { 00380 /* 3 node BJT */ 00381 $$ = spice_create_device ($1); 00382 spice_append_str_value ($$, $2, HINT_NODE); 00383 spice_append_str_value ($$, $3, HINT_NODE); 00384 spice_append_str_value ($$, $4, HINT_NODE); 00385 spice_append_str_value ($$, $5, HINT_NAME); 00386 $$->values = netlist_append_values ($$->values, $6); 00387 } 00388 | Bipolar_Device Node Node Node Node MODEL_Ident DEVICE_List_2 { 00389 /* 4 node BJT */ 00390 $$ = spice_create_device ($1); 00391 spice_append_str_value ($$, $2, HINT_NODE); 00392 spice_append_str_value ($$, $3, HINT_NODE); 00393 spice_append_str_value ($$, $4, HINT_NODE); 00394 spice_append_str_value ($$, $5, HINT_NODE); 00395 spice_append_str_value ($$, $6, HINT_NAME); 00396 $$->values = netlist_append_values ($$->values, $7); 00397 } 00398 | MOSFET_Device Node Node Node Node MODEL_Ident DEVICE_List_3 { 00399 /* MOS */ 00400 $$ = spice_create_device ($1); 00401 spice_append_str_value ($$, $2, HINT_NODE); 00402 spice_append_str_value ($$, $3, HINT_NODE); 00403 spice_append_str_value ($$, $4, HINT_NODE); 00404 spice_append_str_value ($$, $5, HINT_NODE); 00405 spice_append_str_value ($$, $6, HINT_NAME); 00406 $$->values = netlist_append_values ($$->values, $7); 00407 } 00408 | MESFET_Device Node Node Node MODEL_Ident DEVICE_List_2 { 00409 /* MES */ 00410 $$ = spice_create_device ($1); 00411 spice_append_str_value ($$, $2, HINT_NODE); 00412 spice_append_str_value ($$, $3, HINT_NODE); 00413 spice_append_str_value ($$, $4, HINT_NODE); 00414 spice_append_str_value ($$, $5, HINT_NAME); 00415 $$->values = netlist_append_values ($$->values, $6); 00416 } 00417 | TRAN_Action ValueList Eol { 00418 /* transient analysis */ 00419 $$ = spice_create_action ($1, strdup ($1)); 00420 $$->values = $2; 00421 } 00422 | PLOT_Action SIM_Type PLOT_List Eol { 00423 /* plotting */ 00424 $$ = spice_create_action ($1, strdup ($1)); 00425 spice_append_str_value ($$, $2, HINT_NAME); 00426 $$->values = netlist_append_values ($$->values, $3); 00427 } 00428 | AC_Action Expr Eol { 00429 /* AC analysis */ 00430 $$ = spice_create_action ($1, strdup ($1)); 00431 $$->values = $2; 00432 } 00433 | DC_Action Eol { 00434 /* single DC analysis */ 00435 $$ = spice_create_action ($1, strdup ($1)); 00436 } 00437 | DC_Action DC_List Eol { 00438 /* DC analysis first order */ 00439 $$ = spice_create_action ($1, strdup ($1)); 00440 $$->values = $2; 00441 } 00442 | DC_Action DC_List DC_List Eol { 00443 /* DC analysis second order */ 00444 $$ = spice_create_action ($1, strdup ($1)); 00445 $$->values = netlist_append_values ($2, $3); 00446 } 00447 | PRINT_Action SIM_Type PRINT_List Eol { 00448 /* printing specifying the analysis type */ 00449 $$ = spice_create_action ($1, strdup ($1)); 00450 spice_append_str_value ($$, $2, HINT_NAME); 00451 $$->values = netlist_append_values ($$->values, $3); 00452 } 00453 | PRINT_Action PRINT_List Eol { 00454 /* printing */ 00455 $$ = spice_create_action ($1, strdup ($1)); 00456 $$->values = $2; 00457 } 00458 | PRINT_Action SIM_Type ALL_Special Eol { 00459 /* printing */ 00460 $$ = spice_create_action ($1, strdup ($1)); 00461 spice_append_str_value ($$, $2, HINT_NAME); 00462 spice_append_str_value ($$, $3, HINT_NAME); 00463 } 00464 | OPTIONS_Action OPTIONS_List Eol { 00465 /* general analysis options */ 00466 $$ = spice_create_action ($1, strdup ($1)); 00467 $$->values = $2; 00468 } 00469 | TEMP_Action ValueList Eol { 00470 /* temperatur analysis (Spice 2g6) */ 00471 $$ = spice_create_action ($1, strdup ($1)); 00472 $$->values = $2; 00473 } 00474 | WIDTH_Action PairList Eol { 00475 /* TODO: default width of ??? */ 00476 $$ = spice_create_action ($1, strdup ($1)); 00477 $$->values = $2; 00478 } 00479 | NOISE_Action VOLTAGE_Output IV_Reference Expr Eol { 00480 /* noise analysis */ 00481 $$ = spice_create_action ($1, strdup ($1)); 00482 $$->values = netlist_append_values ($$->values, $2); 00483 spice_append_str_value ($$, $3, HINT_NAME); 00484 $$->values = netlist_append_values ($$->values, $4); 00485 } 00486 | PZ_Action Node Node Node Node CurVol PoleZero Eol { 00487 /* pole-zero analysis */ 00488 $$ = spice_create_action ($1, strdup ($1)); 00489 spice_append_str_value ($$, $2, HINT_NODE); 00490 spice_append_str_value ($$, $3, HINT_NODE); 00491 spice_append_str_value ($$, $4, HINT_NODE); 00492 spice_append_str_value ($$, $5, HINT_NODE); 00493 spice_append_str_value ($$, $6, HINT_NAME); 00494 spice_append_str_value ($$, $7, HINT_NAME); 00495 } 00496 | X_Device NodeList Eol { 00497 /* subcircuit call */ 00498 $$ = spice_create_device ($1); 00499 spice_set_last_hint ($2, HINT_NAME); 00500 $$->values = $2; 00501 } 00502 | S_Device Node Node Node Node MODEL_Ident SWITCH_State Eol { 00503 /* voltage controlled switch */ 00504 $$ = spice_create_device ($1); 00505 spice_append_str_value ($$, $2, HINT_NODE); 00506 spice_append_str_value ($$, $3, HINT_NODE); 00507 spice_append_str_value ($$, $4, HINT_NODE); 00508 spice_append_str_value ($$, $5, HINT_NODE); 00509 spice_append_str_value ($$, $6, HINT_NAME); 00510 $$->values = netlist_append_values ($$->values, $7); 00511 } 00512 | W_Device Node Node V_Source MODEL_Ident SWITCH_State Eol { 00513 /* current controlled switch */ 00514 $$ = spice_create_device ($1); 00515 spice_append_str_value ($$, $2, HINT_NODE); 00516 spice_append_str_value ($$, $3, HINT_NODE); 00517 spice_append_str_value ($$, $4, HINT_NAME); 00518 spice_append_str_value ($$, $5, HINT_NAME); 00519 $$->values = netlist_append_values ($$->values, $6); 00520 } 00521 | O_Device Node Node Node Node MODEL_Ident Eol { 00522 /* lossy transline */ 00523 $$ = spice_create_device ($1); 00524 spice_append_str_value ($$, $2, HINT_NODE); 00525 spice_append_str_value ($$, $3, HINT_NODE); 00526 spice_append_str_value ($$, $4, HINT_NODE); 00527 spice_append_str_value ($$, $5, HINT_NODE); 00528 spice_append_str_value ($$, $6, HINT_NAME); 00529 } 00530 | U_Device Node Node Node MODEL_Ident PairList Eol { 00531 /* distributed lossy transline */ 00532 $$ = spice_create_device ($1); 00533 spice_append_str_value ($$, $2, HINT_NODE); 00534 spice_append_str_value ($$, $3, HINT_NODE); 00535 spice_append_str_value ($$, $4, HINT_NODE); 00536 spice_append_str_value ($$, $5, HINT_NAME); 00537 $$->values = netlist_append_values ($$->values, $6); 00538 } 00539 | T_Device Node Node Node Node PairList Eol { 00540 /* lossless transline */ 00541 $$ = spice_create_device ($1); 00542 spice_append_str_value ($$, $2, HINT_NODE); 00543 spice_append_str_value ($$, $3, HINT_NODE); 00544 spice_append_str_value ($$, $4, HINT_NODE); 00545 spice_append_str_value ($$, $5, HINT_NODE); 00546 $$->values = netlist_append_values ($$->values, $6); 00547 } 00548 | T_Device Node Node Node Node PairList IC_Condition_4 Eol { 00549 /* lossless transline and initial condition */ 00550 $$ = spice_create_device ($1); 00551 spice_append_str_value ($$, $2, HINT_NODE); 00552 spice_append_str_value ($$, $3, HINT_NODE); 00553 spice_append_str_value ($$, $4, HINT_NODE); 00554 spice_append_str_value ($$, $5, HINT_NODE); 00555 $$->values = netlist_append_values ($$->values, $6); 00556 $$->values = netlist_append_values ($$->values, $7); 00557 } 00558 | OP_Action Eol { 00559 /* operating point analysis */ 00560 $$ = spice_create_action ($1, strdup ($1)); 00561 } 00562 | SAVE_Action Eol { 00563 /* saving action */ 00564 $$ = spice_create_action ($1, strdup ($1)); 00565 } 00566 | SENS_Action Eol { 00567 /* sensitivity analysis */ 00568 $$ = spice_create_action ($1, strdup ($1)); 00569 } 00570 | TF_Action Eol { 00571 /* transfer function analysis */ 00572 $$ = spice_create_action ($1, strdup ($1)); 00573 } 00574 | FOUR_Action Eol { 00575 /* fourier analysis */ 00576 $$ = spice_create_action ($1, strdup ($1)); 00577 } 00578 | B_Source Eol { 00579 /* non-linear dependent sources */ 00580 $$ = spice_create_device ($1); 00581 } 00582 | DISTO_Action Expr Eol { 00583 /* distortion analysis */ 00584 $$ = spice_create_action ($1, strdup ($1)); 00585 $$->values = $2; 00586 } 00587 | INCLUDE_Action File Eol { 00588 /* file include */ 00589 $$ = spice_create_action ($1, strdup ($1)); 00590 struct value_t * file = create_value (); 00591 file->ident = $2; 00592 file->hint = HINT_NAME; 00593 $$->values = file; 00594 } 00595 | NODESET_Action NODESET_List Eol { 00596 /* nodeset functionality */ 00597 $$ = spice_create_action ($1, strdup ($1)); 00598 $$->values = $2; 00599 } 00600 ; 00601 00602 TC_Value_1: 00603 TC_Special Value { 00604 $$ = NULL; 00605 $$ = spice_create_par_value ($1, $2); 00606 } 00607 ; 00608 00609 TC_Value_2: 00610 TC_Special Value Value { 00611 $$ = NULL; 00612 $$ = spice_create_par_value ($1, $2); 00613 $$ = spice_append_val_values ($$, $3, HINT_NUMBER); 00614 } 00615 ; 00616 00617 IC_Condition_1: 00618 IC_Special Value { 00619 $$ = NULL; 00620 $$ = spice_append_str_values ($$, $1, HINT_NAME); 00621 $$ = spice_append_val_values ($$, $2, HINT_NUMBER); 00622 } 00623 ; 00624 00625 IC_Condition_2: 00626 IC_Special Value Value { 00627 $$ = NULL; 00628 $$ = spice_append_str_values ($$, $1, HINT_NAME); 00629 $$ = spice_append_val_values ($$, $2, HINT_NUMBER); 00630 $$ = spice_append_val_values ($$, $3, HINT_NUMBER); 00631 } 00632 00633 IC_Condition_3: 00634 IC_Special Value Value Value { 00635 $$ = NULL; 00636 $$ = spice_append_str_values ($$, $1, HINT_NAME); 00637 $$ = spice_append_val_values ($$, $2, HINT_NUMBER); 00638 $$ = spice_append_val_values ($$, $3, HINT_NUMBER); 00639 $$ = spice_append_val_values ($$, $4, HINT_NUMBER); 00640 } 00641 ; 00642 00643 IC_Condition_4: 00644 IC_Special Value Value Value Value { 00645 $$ = NULL; 00646 $$ = spice_append_str_values ($$, $1, HINT_NAME); 00647 $$ = spice_append_val_values ($$, $2, HINT_NUMBER); 00648 $$ = spice_append_val_values ($$, $3, HINT_NUMBER); 00649 $$ = spice_append_val_values ($$, $4, HINT_NUMBER); 00650 $$ = spice_append_val_values ($$, $5, HINT_NUMBER); 00651 } 00652 ; 00653 00654 Output_Range: 00655 Value Value { /* range specification during plotting */ 00656 $$ = NULL; 00657 $$ = spice_append_val_values ($$, $1, HINT_NUMBER); 00658 $$ = spice_append_val_values ($$, $2, HINT_NUMBER); 00659 } 00660 ; 00661 00662 VOLTAGE_Output: 00663 Node { // TODO: 2 reduce/reduce, 2 shift/reduce 00664 /* print/plot specification of node voltage */ 00665 $$ = NULL; 00666 $$ = spice_append_str_values ($$, strdup ("V"), HINT_NAME | HINT_MSTART); 00667 $$ = spice_append_str_values ($$, $1, HINT_NODE | HINT_MSTOP); 00668 } 00669 | VoltFunc Node { // TODO: 2 reduce/reduce 00670 /* print/plot specification of node voltage */ 00671 $$ = NULL; 00672 $$ = spice_append_str_values ($$, $1, HINT_NAME | HINT_MSTART); 00673 $$ = spice_append_str_values ($$, $2, HINT_NODE | HINT_MSTOP); 00674 } 00675 | VoltFunc Node Node { 00676 /* print/plot specification of differential node voltages */ 00677 $$ = NULL; 00678 $$ = spice_append_str_values ($$, $1, HINT_NAME | HINT_MSTART); 00679 $$ = spice_append_str_values ($$, $2, HINT_NODE); 00680 $$ = spice_append_str_values ($$, $3, HINT_NODE | HINT_MSTOP); 00681 } 00682 ; 00683 00684 /* reference to a current or voltage source */ 00685 IV_Reference: I_Source | V_Source; 00686 00687 CURRENT_Output: 00688 CurrFunc V_Source { 00689 /* print/plot specification of branch current */ 00690 $$ = NULL; 00691 $$ = spice_append_str_values ($$, $1, HINT_NAME | HINT_MSTART); 00692 $$ = spice_append_str_values ($$, $2, HINT_NAME | HINT_MSTOP); 00693 } 00694 | BranchFunc { 00695 /* print/plot specification of branch current */ 00696 $$ = NULL; 00697 $$ = spice_append_str_values ($$, strdup ("I"), HINT_NAME | HINT_MSTART); 00698 $$ = spice_append_str_values ($$, $1, HINT_NAME | HINT_MSTOP); 00699 } 00700 | OpFunc { 00701 /* print/plot specification of operating point */ 00702 $$ = NULL; 00703 $$ = spice_append_str_values ($$, strdup ("OP"), HINT_NAME | HINT_MSTART); 00704 $$ = spice_append_str_values ($$, $1, HINT_NAME | HINT_MSTOP); 00705 } 00706 ; 00707 00708 PLOT_List: /* nothing */ { $$ = NULL; } 00709 | VOLTAGE_Output PLOT_List { 00710 $$ = netlist_append_values ($1, $2); 00711 } 00712 | VOLTAGE_Output Output_Range PLOT_List { 00713 $$ = netlist_append_values ($1, $2); 00714 $$ = netlist_append_values ($$, $3); 00715 } 00716 | CURRENT_Output PLOT_List { 00717 $$ = netlist_append_values ($1, $2); 00718 } 00719 | CURRENT_Output Output_Range PLOT_List { 00720 $$ = netlist_append_values ($1, $2); 00721 $$ = netlist_append_values ($$, $3); 00722 } 00723 ; 00724 00725 SWITCH_State: /* nothing */ { $$ = NULL; } 00726 | ON_Special { 00727 $$ = spice_create_str_value ($1, HINT_NAME); 00728 } 00729 | OFF_Special { 00730 $$ = spice_create_str_value ($1, HINT_NAME); 00731 } 00732 ; 00733 00734 PRINT_List: /* nothing */ { $$ = NULL; } 00735 | VOLTAGE_Output PLOT_List { 00736 $$ = netlist_append_values ($1, $2); 00737 } 00738 | CURRENT_Output PLOT_List { 00739 $$ = netlist_append_values ($1, $2); 00740 } 00741 ; 00742 00743 OPTIONS_List: /* nothing */ { $$ = NULL; } 00744 | Options OPTIONS_List { 00745 $$ = spice_create_str_value ($1, HINT_NAME); 00746 $$ = netlist_append_values ($$, $2); 00747 } 00748 | Identifier Value OPTIONS_List { 00749 $$ = spice_create_par_value ($1, $2); 00750 $$ = netlist_append_values ($$, $3); 00751 } 00752 ; 00753 00754 MODEL_List: /* nothing */ { $$ = NULL; } 00755 | ModelProps MODEL_List { 00756 $$ = spice_create_str_value ($1, HINT_NAME); 00757 $$ = netlist_append_values ($$, $2); 00758 } 00759 | Identifier Value MODEL_List { 00760 $$ = spice_create_par_value ($1, $2); 00761 $$ = netlist_append_values ($$, $3); 00762 } 00763 ; 00764 00765 NODESET_List: /* nothing */ { $$ = NULL; } 00766 | VoltFunc Node Value NODESET_List { 00767 $$ = NULL; 00768 $$ = spice_append_str_values ($$, $1, HINT_NAME | HINT_MSTART); 00769 $$ = spice_append_str_values ($$, $2, HINT_NODE | HINT_MSTOP); 00770 $$ = spice_append_str_values ($$, $3, HINT_NUMBER); 00771 $$ = netlist_append_values ($$, $4); 00772 } 00773 ; 00774 00775 DEVICE_List_1: /* nothing */ { $$ = NULL; } 00776 | TEMP_Special Value DEVICE_List_1 { 00777 $$ = spice_create_par_value ($1, $2); 00778 $$ = netlist_append_values ($$, $3); 00779 } 00780 | Value DEVICE_List_1 { 00781 $$ = spice_create_par_value (strdup ("Area"), $1); 00782 $$ = netlist_append_values ($$, $2); 00783 } 00784 | OFF_Special DEVICE_List_1 { 00785 $$ = spice_create_val_value ($1, HINT_NAME); 00786 $$ = netlist_append_values ($$, $2); 00787 } 00788 | IC_Condition_1 DEVICE_List_1 { 00789 $$ = netlist_append_values ($1, $2); 00790 } 00791 ; 00792 00793 DEVICE_List_2: /* nothing */ { $$ = NULL; } 00794 | TEMP_Special Value DEVICE_List_2 { 00795 $$ = spice_create_par_value ($1, $2); 00796 $$ = netlist_append_values ($$, $3); 00797 } 00798 | Value DEVICE_List_2 { 00799 $$ = spice_create_par_value (strdup ("Area"), $1); 00800 $$ = netlist_append_values ($$, $2); 00801 } 00802 | OFF_Special DEVICE_List_2 { 00803 $$ = spice_create_val_value ($1, HINT_NAME); 00804 $$ = netlist_append_values ($$, $2); 00805 } 00806 | IC_Condition_2 DEVICE_List_2 { 00807 $$ = netlist_append_values ($1, $2); 00808 } 00809 | MOS_Special Value DEVICE_List_2 { 00810 $$ = spice_create_par_value ($1, $2); 00811 $$ = netlist_append_values ($$, $3); 00812 } 00813 ; 00814 00815 DEVICE_List_3: /* nothing */ { $$ = NULL; } 00816 | TEMP_Special Value DEVICE_List_3 { 00817 $$ = spice_create_par_value ($1, $2); 00818 $$ = netlist_append_values ($$, $3); 00819 } 00820 | MOS_Special Value DEVICE_List_3 { 00821 $$ = spice_create_par_value ($1, $2); 00822 $$ = netlist_append_values ($$, $3); 00823 } 00824 | Value DEVICE_List_3 { 00825 $$ = spice_create_val_value ($1, HINT_NUMBER); 00826 $$ = netlist_append_values ($$, $2); 00827 } 00828 | OFF_Special DEVICE_List_3 { 00829 $$ = spice_create_val_value ($1, HINT_NAME); 00830 $$ = netlist_append_values ($$, $2); 00831 } 00832 | IC_Condition_3 DEVICE_List_3 { 00833 $$ = netlist_append_values ($1, $2); 00834 } 00835 ; 00836 00837 MODEL_Ident: Identifier | MODEL_Spec; 00838 00839 DC_List: 00840 IV_Reference Value Value Value { 00841 /* identification of a DC sweep */ 00842 $$ = NULL; 00843 $$ = spice_append_str_values ($$, $1, HINT_NAME | HINT_MSTART); 00844 $$ = spice_append_val_values ($$, $2, HINT_NUMBER); 00845 $$ = spice_append_val_values ($$, $3, HINT_NUMBER); 00846 $$ = spice_append_val_values ($$, $4, HINT_NUMBER | HINT_MSTOP); 00847 } 00848 ; 00849 00850 Value: Digits | Floats; 00851 00852 Node: Digits | Nodes | Identifier; 00853 00854 FH_Node: Node | V_Source; 00855 00856 PairList: /* nothing */ { $$ = NULL; } 00857 | Identifier Value PairList { 00858 $$ = spice_create_par_value ($1, $2); 00859 $$->next = $3; 00860 } 00861 ; 00862 00863 ValueList: /* nothing */ { $$ = NULL; } 00864 | Value ValueList { 00865 $$ = spice_create_val_value ($1, HINT_NUMBER); 00866 $$->next = $2; 00867 } 00868 ; 00869 00870 NodeValueList: /* nothing */ { $$ = NULL; } 00871 | Node NodeValueList { 00872 $$ = spice_create_str_value ($1, HINT_NODE); 00873 $$->next = $2; 00874 } 00875 | Floats NodeValueList { 00876 $$ = spice_create_val_value ($1, HINT_NUMBER); 00877 $$->next = $2; 00878 } 00879 ; 00880 00881 NodeList: /* nothing */ { $$ = NULL; } 00882 | Node NodeList { 00883 $$ = spice_create_str_value ($1, HINT_NODE); 00884 $$->next = $2; 00885 } 00886 ; 00887 00888 VSourceList: /* nothing */ { $$ = NULL; } 00889 | V_Source VSourceList { 00890 $$ = spice_create_str_value ($1, HINT_NAME); 00891 $$->next = $2; 00892 } 00893 ; 00894 00895 Expr: 00896 Function ValueList { 00897 $$ = spice_create_str_value ($1, HINT_NAME | HINT_MSTART); 00898 spice_add_last_hint ($2, HINT_MSTOP); 00899 $$->next = $2; 00900 } 00901 ; 00902 00903 ExprList: /* nothing */ { $$ = NULL; } 00904 | Expr ExprList { 00905 $$ = netlist_append_values ($1, $2); 00906 } 00907 ; 00908 00909 Subcircuit: 00910 BeginSub SubBody EndSub { 00911 $1->sub = $2; 00912 $$ = $1; 00913 $2 = NULL; 00914 } 00915 ; 00916 00917 BeginSub: 00918 SUBCKT_Action SubCkt_Ident NodeList Eol { 00919 $$ = spice_create_action ($1, $2); 00920 $$->values = $3; 00921 } 00922 ; 00923 00924 SubBody: /* nothing */ { $$ = NULL; } 00925 | SubBodyLine SubBody { /* chain definitions here */ 00926 if ($1) { 00927 $1->next = $2; 00928 $$ = $1; 00929 } 00930 else { 00931 $$ = $2; 00932 } 00933 } 00934 ; 00935 00936 SubCkt_Ident: Identifier; 00937 00938 EndSub: 00939 ENDS_Action { /* nothing to do */ } 00940 | ENDS_Action SubCkt_Ident { free ($2); /* nothing to do */ } 00941 ; 00942 00943 SubBodyLine: 00944 DefinitionLine { /* chain definitions here */ 00945 if ($1) { 00946 $1->next = $$; 00947 $$ = $1; 00948 } 00949 } 00950 | Subcircuit { /* do nothing here, see subcircuit rule */ } 00951 | Eol { 00952 $$ = NULL; 00953 } 00954 ; 00955 00956 %% 00957 00958 int spice_error (const char * error) { 00959 fprintf (stderr, "line %d: %s\n", spice_lineno, error); 00960 return 0; 00961 }