Qucs-core
0.0.19
|
00001 /* -*-c++-*- */ 00002 00003 %{ 00004 /* 00005 * parse_netlist.y - parser for the Qucs netlist 00006 * 00007 * Copyright (C) 2003, 2004, 2005, 2006, 2007 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 00036 #define YYERROR_VERBOSE 42 00037 #define YYDEBUG 1 00038 #define YYMAXDEPTH 1000000 00039 00040 #include "check_netlist.h" 00041 #include "logging.h" 00042 #include "equation.h" 00043 #include "range.h" 00044 00045 using namespace qucs; 00046 00047 %} 00048 00049 %name-prefix "netlist_" 00050 00051 %token InvalidCharacter 00052 %token Identifier 00053 %token Assign 00054 %token ScaleOrUnit 00055 %token Eol 00056 %token Eqn 00057 %token DefSub 00058 %token EndSub 00059 %token REAL 00060 %token IMAG 00061 %token COMPLEX 00062 %token Character 00063 %token STRING 00064 00065 %right '=' 00066 %right '?' ':' 00067 %left Or 00068 %left And 00069 %left NotEqual Equal 00070 %left Less Greater LessOrEqual GreaterOrEqual 00071 %left '-' '+' 00072 %left '*' '/' '%' 00073 %right Not 00074 %left NEG /* unary negation */ 00075 %left POS /* unary non-negation */ 00076 %right '^' 00077 00078 %union { 00079 char * ident; 00080 char * str; 00081 double d; 00082 char chr; 00083 struct definition_t * definition; 00084 struct definition_t * subcircuit; 00085 struct node_t * node; 00086 struct pair_t * pair; 00087 struct value_t * value; 00088 struct { 00089 double r; 00090 double i; 00091 } c; 00092 qucs::eqn::node * eqn; 00093 qucs::eqn::constant * con; 00094 qucs::eqn::reference * ref; 00095 qucs::eqn::application * app; 00096 qucs::eqn::assignment * assign; 00097 } 00098 00099 %type <ident> Identifier Assign NodeIdentifier InstanceIdentifier 00100 %type <str> ScaleOrUnit 00101 %type <d> REAL IMAG 00102 %type <c> COMPLEX 00103 %type <chr> Character 00104 %type <str> STRING 00105 %type <definition> DefinitionLine ActionLine DefBody DefBodyLine EquationLine 00106 %type <definition> InputList InputLine 00107 %type <subcircuit> DefBegin SubcircuitBody 00108 %type <node> NodeList 00109 %type <pair> PairList 00110 %type <value> PropertyValue ValueList Value PropertyReal 00111 %type <eqn> EquationList Expression ExpressionList 00112 %type <assign> Equation 00113 %type <con> Constant 00114 %type <ref> Reference 00115 %type <app> Application Range Matrix Vector 00116 %type <eqn> ExpressionMatrix ExpressionVector 00117 %type <eqn> ExpressionRowList ExpressionCol ExpressionColList 00118 00119 %% 00120 00121 Input: 00122 InputList { 00123 definition_root = $1; 00124 } 00125 ; 00126 00127 InputList: /* nothing */ { $$ = NULL; } 00128 | InputLine InputList { 00129 if ($1) { 00130 $1->next = $2; 00131 $$ = $1; 00132 } else { 00133 $$ = $2; 00134 } 00135 } 00136 ; 00137 00138 InputLine: 00139 SubcircuitBody { 00140 $$ = $1; 00141 } 00142 | EquationLine 00143 | ActionLine 00144 | DefinitionLine 00145 | Eol { 00146 $$ = NULL; 00147 } 00148 ; 00149 00150 /* An action line in the netlist, i.e. the specification of the type 00151 of simulation to be performed */ 00152 ActionLine: 00153 '.' Identifier ':' InstanceIdentifier PairList Eol { 00154 $$ = (struct definition_t *) calloc (sizeof (struct definition_t), 1); 00155 $$->action = PROP_ACTION; 00156 $$->type = $2; 00157 $$->instance = $4; 00158 $$->pairs = $5; 00159 $$->line = netlist_lineno; 00160 } 00161 ; 00162 00163 /* A definition line in the netlist, i.e. a component specification 00164 such as R:R1 _net0 gnd R="50 Ohm" Temp="26.85" Tc1="0.0" Tc2="0.0" Tnom="26.85" 00165 */ 00166 DefinitionLine: 00167 Identifier ':' InstanceIdentifier NodeList PairList Eol { 00168 $$ = (struct definition_t *) calloc (sizeof (struct definition_t), 1); 00169 $$->action = PROP_COMPONENT; 00170 $$->type = $1; 00171 $$->instance = $3; 00172 $$->nodes = $4; 00173 $$->pairs = $5; 00174 $$->line = netlist_lineno; 00175 } 00176 ; 00177 00178 InstanceIdentifier: 00179 Identifier { $$ = $1; } 00180 | ScaleOrUnit { $$ = $1; } 00181 ; 00182 00183 NodeIdentifier: 00184 Identifier { $$ = $1; } 00185 | ScaleOrUnit { $$ = $1; } 00186 ; 00187 00188 /* List of nodes for a component */ 00189 NodeList: /* nothing */ { $$ = NULL; } 00190 | NodeIdentifier NodeList { 00191 $$ = (struct node_t *) calloc (sizeof (struct node_t), 1); 00192 $$->node = $1; 00193 $$->next = $2; 00194 } 00195 ; 00196 00197 /* Assigns the list of key-value pairs x="y" */ 00198 PairList: /* nothing */ { $$ = NULL; } 00199 | Assign Value PairList { 00200 $$ = (struct pair_t *) calloc (sizeof (struct pair_t), 1); 00201 $$->key = $1; 00202 $$->value = $2; 00203 $$->next = $3; 00204 } 00205 | Assign NoneValue PairList { 00206 if (0) { 00207 $$ = (struct pair_t *) calloc (sizeof (struct pair_t), 1); 00208 $$->key = $1; 00209 $$->value = NULL; 00210 $$->next = $3; 00211 } else { 00212 free ($1); 00213 $$ = $3; 00214 } 00215 } 00216 ; 00217 00218 /* A empty value in a pair list */ 00219 NoneValue: { /* nothing */ } 00220 | '"' '"' { /* also nothing */ } 00221 ; 00222 00223 /* A property value, can either be on its own or enclosed in quotes */ 00224 Value: 00225 PropertyValue { 00226 $$ = $1; 00227 } 00228 | '"' PropertyValue '"' { 00229 $$ = $2; 00230 } 00231 ; 00232 00233 PropertyReal: 00234 REAL { 00235 $$ = create_value (); 00236 $$->value = $1; 00237 } 00238 | REAL ScaleOrUnit { 00239 $$ = create_value (); 00240 $$->value = $1; 00241 $$->scale = $2; 00242 } 00243 | REAL ScaleOrUnit ScaleOrUnit { 00244 $$ = create_value (); 00245 $$->value = $1; 00246 $$->scale = $2; 00247 $$->unit = $3; 00248 } 00249 ; 00250 00251 PropertyValue: 00252 PropertyReal { 00253 $$ = $1; 00254 } 00255 | InstanceIdentifier { 00256 $$ = create_value (); 00257 $$->ident = $1; 00258 } 00259 | '[' InstanceIdentifier ']' { 00260 $$ = create_value (); 00261 $$->ident = $2; 00262 } 00263 | '[' ValueList ']' { 00264 $$ = $2; 00265 } 00266 ; 00267 00268 ValueList: /* nothing */ { $$ = NULL; } 00269 | PropertyReal { 00270 $1->next = NULL; 00271 $$ = $1; 00272 } 00273 | PropertyReal ';' ValueList { 00274 $1->next = $3; 00275 $$ = $1; 00276 } 00277 ; 00278 00279 EquationLine: 00280 Eqn ':' InstanceIdentifier Equation EquationList Eol { 00281 /* create equation definition */ 00282 $$ = (struct definition_t *) calloc (sizeof (struct definition_t), 1); 00283 $$->type = strdup ("Eqn"); 00284 $$->instance = $3; 00285 $$->action = PROP_ACTION; 00286 $$->line = netlist_lineno; 00287 $4->setInstance ($3); 00288 $4->setNext ($5); 00289 $4->applyInstance (); 00290 $$->eqns = $4; 00291 } 00292 ; 00293 00294 EquationList: /* nothing */ { $$ = NULL; } 00295 | Equation EquationList { 00296 $1->setNext ($2); 00297 $$ = $1; 00298 } 00299 ; 00300 00301 Equation: 00302 Assign '"' Expression '"' { 00303 $$ = new eqn::assignment (); 00304 $$->result = $1; 00305 $$->body = $3; 00306 } 00307 ; 00308 00309 Expression: 00310 Constant { 00311 $$ = $1; 00312 } 00313 | Reference { 00314 $$ = $1; 00315 } 00316 | Application { 00317 $$ = $1; 00318 } 00319 | '(' Expression ')' { 00320 $$ = $2; 00321 } 00322 | '[' Vector ']' { 00323 $$ = $2; 00324 } 00325 | '[' Matrix ']' { 00326 $$ = $2; 00327 } 00328 ; 00329 00330 ExpressionCol: 00331 Expression ExpressionColList { 00332 $1->appendNodes ($2); 00333 $$ = $1; 00334 } 00335 ; 00336 00337 ExpressionColList: /* nothing */ { $$ = NULL; } 00338 | ',' Expression ExpressionColList { 00339 $2->appendNodes ($3); 00340 $$ = $2; 00341 } 00342 ; 00343 00344 ExpressionVector: 00345 ExpressionCol 00346 ; 00347 00348 Vector: 00349 ExpressionVector { 00350 $$ = new eqn::application (); 00351 $$->n = strdup ("vector"); 00352 $$->nargs = $1->count (); 00353 $$->args = $1; 00354 } 00355 ; 00356 00357 ExpressionRowList: /* nothing */ { $$ = NULL; } 00358 | ';' ExpressionCol ExpressionRowList { 00359 eqn::constant * c = new eqn::constant (eqn::TAG_CHAR); 00360 c->chr = ';'; 00361 c->appendNodes ($2); 00362 $2->appendNodes ($3); 00363 $$ = c; 00364 } 00365 ; 00366 00367 ExpressionMatrix: 00368 ExpressionCol ';' ExpressionCol ExpressionRowList { 00369 eqn::constant * c = new eqn::constant (eqn::TAG_CHAR); 00370 c->chr = ';'; 00371 c->appendNodes ($3); 00372 $3->appendNodes ($4); 00373 $1->appendNodes (c); 00374 $$ = $1; 00375 } 00376 ; 00377 00378 Matrix: 00379 ExpressionMatrix { 00380 $$ = new eqn::application (); 00381 $$->n = strdup ("matrix"); 00382 $$->nargs = $1->count (); 00383 $$->args = $1; 00384 } 00385 ; 00386 00387 Constant: 00388 REAL { 00389 $$ = new eqn::constant (eqn::TAG_DOUBLE); 00390 $$->d = $1; 00391 } 00392 | IMAG { 00393 $$ = new eqn::constant (eqn::TAG_COMPLEX); 00394 $$->c = new nr_complex_t (0.0, $1); 00395 } 00396 | Character { 00397 $$ = new eqn::constant (eqn::TAG_CHAR); 00398 $$->chr = $1; 00399 } 00400 | STRING { 00401 $$ = new eqn::constant (eqn::TAG_STRING); 00402 $$->s = $1; 00403 } 00404 ; 00405 00406 Range: 00407 Expression ':' Expression { 00408 $$ = new eqn::application (); 00409 $$->n = strdup ("range"); 00410 $$->nargs = 2; 00411 $1->append ($3); 00412 $$->args = $1; 00413 } 00414 | ':' Expression { 00415 $$ = new eqn::application (); 00416 $$->n = strdup ("range"); 00417 $$->nargs = 2; 00418 eqn::constant * c = new eqn::constant (eqn::TAG_CHAR); 00419 c->chr = '?'; 00420 c->append ($2); 00421 $$->args = c; 00422 } 00423 | Expression ':' { 00424 $$ = new eqn::application (); 00425 $$->n = strdup ("range"); 00426 $$->nargs = 2; 00427 eqn::constant * c = new eqn::constant (eqn::TAG_CHAR); 00428 c->chr = '?'; 00429 $1->append (c); 00430 $$->args = $1; 00431 } 00432 | ':' { 00433 $$ = new eqn::application (); 00434 $$->n = strdup ("range"); 00435 $$->nargs = 2; 00436 eqn::constant * c1 = new eqn::constant (eqn::TAG_CHAR); 00437 eqn::constant * c2 = new eqn::constant (eqn::TAG_CHAR); 00438 c1->chr = '?'; 00439 c2->chr = '?'; 00440 c1->append (c2); 00441 $$->args = c1; 00442 } 00443 ; 00444 00445 Reference: 00446 Identifier { 00447 $$ = new eqn::reference (); 00448 $$->n = $1; 00449 } 00450 ; 00451 00452 Application: 00453 Identifier '(' ExpressionList ')' { 00454 $$ = new eqn::application (); 00455 $$->n = $1; 00456 $$->nargs = $3->count (); 00457 $$->args = $3; 00458 } 00459 | Reference '[' ExpressionList ']' { 00460 $$ = new eqn::application (); 00461 $$->n = strdup ("array"); 00462 $$->nargs = 1 + $3->count (); 00463 $1->setNext ($3); 00464 $$->args = $1; 00465 } 00466 | Expression '+' Expression { 00467 $$ = new eqn::application (); 00468 $$->n = strdup ("+"); 00469 $$->nargs = 2; 00470 $1->append ($3); 00471 $$->args = $1; 00472 } 00473 | Expression '-' Expression { 00474 $$ = new eqn::application (); 00475 $$->n = strdup ("-"); 00476 $$->nargs = 2; 00477 $1->append ($3); 00478 $$->args = $1; 00479 } 00480 | Expression '*' Expression { 00481 $$ = new eqn::application (); 00482 $$->n = strdup ("*"); 00483 $$->nargs = 2; 00484 $1->append ($3); 00485 $$->args = $1; 00486 } 00487 | Expression '/' Expression { 00488 $$ = new eqn::application (); 00489 $$->n = strdup ("/"); 00490 $$->nargs = 2; 00491 $1->append ($3); 00492 $$->args = $1; 00493 } 00494 | Expression '%' Expression { 00495 $$ = new eqn::application (); 00496 $$->n = strdup ("%"); 00497 $$->nargs = 2; 00498 $1->append ($3); 00499 $$->args = $1; 00500 } 00501 | '+' Expression %prec POS { 00502 $$ = new eqn::application (); 00503 $$->n = strdup ("+"); 00504 $$->nargs = 1; 00505 $$->args = $2; 00506 } 00507 | '-' Expression %prec NEG { 00508 $$ = new eqn::application (); 00509 $$->n = strdup ("-"); 00510 $$->nargs = 1; 00511 $$->args = $2; 00512 } 00513 | Expression '^' Expression { 00514 $$ = new eqn::application (); 00515 $$->n = strdup ("^"); 00516 $$->nargs = 2; 00517 $1->append ($3); 00518 $$->args = $1; 00519 } 00520 | Expression '?' Expression ':' Expression { 00521 $$ = new eqn::application (); 00522 $$->n = strdup ("?:"); 00523 $$->nargs = 3; 00524 $1->append ($3); 00525 $1->append ($5); 00526 $$->args = $1; 00527 } 00528 | Expression Less Expression { 00529 $$ = new eqn::application (); 00530 $$->n = strdup ("<"); 00531 $$->nargs = 2; 00532 $1->append ($3); 00533 $$->args = $1; 00534 } 00535 | Expression Greater Expression { 00536 $$ = new eqn::application (); 00537 $$->n = strdup (">"); 00538 $$->nargs = 2; 00539 $1->append ($3); 00540 $$->args = $1; 00541 } 00542 | Expression GreaterOrEqual Expression { 00543 $$ = new eqn::application (); 00544 $$->n = strdup (">="); 00545 $$->nargs = 2; 00546 $1->append ($3); 00547 $$->args = $1; 00548 } 00549 | Expression LessOrEqual Expression { 00550 $$ = new eqn::application (); 00551 $$->n = strdup ("<="); 00552 $$->nargs = 2; 00553 $1->append ($3); 00554 $$->args = $1; 00555 } 00556 | Expression Equal Expression { 00557 $$ = new eqn::application (); 00558 $$->n = strdup ("=="); 00559 $$->nargs = 2; 00560 $1->append ($3); 00561 $$->args = $1; 00562 } 00563 | Expression NotEqual Expression { 00564 $$ = new eqn::application (); 00565 $$->n = strdup ("!="); 00566 $$->nargs = 2; 00567 $1->append ($3); 00568 $$->args = $1; 00569 } 00570 | Not Expression { 00571 $$ = new eqn::application (); 00572 $$->n = strdup ("!"); 00573 $$->nargs = 1; 00574 $$->args = $2; 00575 } 00576 | Expression And Expression { 00577 $$ = new eqn::application (); 00578 $$->n = strdup ("&&"); 00579 $$->nargs = 2; 00580 $1->append ($3); 00581 $$->args = $1; 00582 } 00583 | Expression Or Expression { 00584 $$ = new eqn::application (); 00585 $$->n = strdup ("||"); 00586 $$->nargs = 2; 00587 $1->append ($3); 00588 $$->args = $1; 00589 } 00590 ; 00591 00592 ExpressionList: /* nothing */ { $$ = NULL; } 00593 | Expression { 00594 $$ = $1; 00595 } 00596 | Range { 00597 $$ = $1; 00598 } 00599 | Expression ',' ExpressionList { 00600 $1->setNext ($3); 00601 $$ = $1; 00602 } 00603 | Range ',' ExpressionList { 00604 $1->setNext ($3); 00605 $$ = $1; 00606 } 00607 ; 00608 00609 SubcircuitBody: 00610 DefBegin DefBody DefEnd { /* a full subcircuit definition found */ 00611 $1->sub = $2; 00612 $$ = $1; 00613 $2 = NULL; 00614 } 00615 ; 00616 00617 DefBegin: 00618 DefSub InstanceIdentifier NodeList PairList Eol { 00619 /* create subcircuit definition right here */ 00620 $$ = (struct definition_t *) calloc (sizeof (struct definition_t), 1); 00621 $$->type = strdup ("Def"); 00622 $$->instance = $2; 00623 $$->nodes = $3; 00624 $$->pairs = $4; 00625 $$->action = PROP_ACTION; 00626 $$->line = netlist_lineno; 00627 } 00628 ; 00629 00630 DefBody: /* nothing */ { $$ = NULL; } 00631 | DefBodyLine DefBody { /* chain definitions here */ 00632 if ($1) { 00633 $1->next = $2; 00634 $$ = $1; 00635 } 00636 else { 00637 $$ = $2; 00638 } 00639 } 00640 ; 00641 00642 DefEnd: 00643 EndSub Eol { /* nothing to do */ } 00644 ; 00645 00646 DefBodyLine: 00647 DefinitionLine { /* chain definitions here */ 00648 $1->next = $$; 00649 $$ = $1; 00650 } 00651 | EquationLine { /* chain definitions here */ 00652 $1->next = $$; 00653 $$ = $1; 00654 } 00655 | SubcircuitBody { /* do nothing here, see subcircuit rule */ } 00656 | Eol { 00657 $$ = NULL; 00658 } 00659 ; 00660 00661 00662 %% 00663 00664 int netlist_error (const char * error) { 00665 logprint (LOG_ERROR, "line %d: %s\n", netlist_lineno, error); 00666 return 0; 00667 }