Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
parse_netlist.y
Go to the documentation of this file.
1 /* -*-c++-*- */
2 
3 %{
4 /*
5  * parse_netlist.y - parser for the Qucs netlist
6  *
7  * Copyright (C) 2003, 2004, 2005, 2006, 2007 Stefan Jahn <stefan@lkcc.org>
8  *
9  * This is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2, or (at your option)
12  * any later version.
13  *
14  * This software is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this package; see the file COPYING. If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  *
24  * $Id$
25  *
26  */
27 
28 #if HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #define YYERROR_VERBOSE 42
37 #define YYDEBUG 1
38 #define YYMAXDEPTH 1000000
39 
40 #include "check_netlist.h"
41 #include "logging.h"
42 #include "equation.h"
43 #include "range.h"
44 
45 using namespace qucs;
46 
47 %}
48 
49 %name-prefix="netlist_"
50 
52 %token Identifier
53 %token Assign
54 %token ScaleOrUnit
55 %token Eol
56 %token Eqn
57 %token DefSub
58 %token EndSub
59 %token REAL
60 %token IMAG
61 %token COMPLEX
62 %token Character
63 %token STRING
64 
65 %right '='
66 %right '?' ':'
67 %left Or
68 %left And
69 %left NotEqual Equal
70 %left Less Greater LessOrEqual GreaterOrEqual
71 %left '-' '+'
72 %left '*' '/' '%'
73 %right Not
74 %left NEG /* unary negation */
75 %left POS /* unary non-negation */
76 %right '^'
77 
78 %union {
79  char * ident;
80  char * str;
81  double d;
82  char chr;
83  struct definition_t * definition;
85  struct node_t * node;
86  struct pair_t * pair;
87  struct value_t * value;
88  struct {
89  double r;
90  double i;
91  } c;
93  qucs::eqn::constant * con;
96  qucs::eqn::assignment * assign;
97 }
98 
99 %type <ident> Identifier Assign NodeIdentifier InstanceIdentifier
100 %type <str> ScaleOrUnit
101 %type <d> REAL IMAG
102 %type <c> COMPLEX
103 %type <chr> Character
104 %type <str> STRING
105 %type <definition> DefinitionLine ActionLine DefBody DefBodyLine EquationLine
106 %type <definition> InputList InputLine
107 %type <subcircuit> DefBegin SubcircuitBody
108 %type <node> NodeList
109 %type <pair> PairList
112 %type <assign> Equation
113 %type <con> Constant
114 %type <ref> Reference
115 %type <app> Application Range Matrix Vector
116 %type <eqn> ExpressionMatrix ExpressionVector
117 %type <eqn> ExpressionRowList ExpressionCol ExpressionColList
118 
119 %%
120 
121 Input:
122  InputList {
123  definition_root = $1;
124  }
125 ;
126 
127 InputList: /* nothing */ { $$ = NULL; }
128  | InputLine InputList {
129  if ($1) {
130  $1->next = $2;
131  $$ = $1;
132  } else {
133  $$ = $2;
134  }
135  }
136 ;
138 InputLine:
140  $$ = $1;
141  }
142  | EquationLine
143  | ActionLine
145  | Eol {
146  $$ = NULL;
147  }
148 ;
149 
150 /* An action line in the netlist, i.e. the specification of the type
151  of simulation to be performed */
152 ActionLine:
154  $$ = (struct definition_t *) calloc (sizeof (struct definition_t), 1);
155  $$->action = PROP_ACTION;
156  $$->type = $2;
157  $$->instance = $4;
158  $$->pairs = $5;
159  $$->line = netlist_lineno;
160  }
161 ;
162 
163 /* A definition line in the netlist, i.e. a component specification
164  such as R:R1 _net0 gnd R="50 Ohm" Temp="26.85" Tc1="0.0" Tc2="0.0" Tnom="26.85"
165  */
168  $$ = (struct definition_t *) calloc (sizeof (struct definition_t), 1);
169  $$->action = PROP_COMPONENT;
170  $$->type = $1;
171  $$->instance = $3;
172  $$->nodes = $4;
173  $$->pairs = $5;
174  $$->line = netlist_lineno;
175  }
176 ;
177 
179  Identifier { $$ = $1; }
180  | ScaleOrUnit { $$ = $1; }
181 ;
182 
183 NodeIdentifier:
184  Identifier { $$ = $1; }
185  | ScaleOrUnit { $$ = $1; }
186 ;
188 /* List of nodes for a component */
189 NodeList: /* nothing */ { $$ = NULL; }
190  | NodeIdentifier NodeList {
191  $$ = (struct node_t *) calloc (sizeof (struct node_t), 1);
192  $$->node = $1;
193  $$->next = $2;
194  }
195 ;
197 /* Assigns the list of key-value pairs x="y" */
198 PairList: /* nothing */ { $$ = NULL; }
199  | Assign Value PairList {
200  $$ = (struct pair_t *) calloc (sizeof (struct pair_t), 1);
201  $$->key = $1;
202  $$->value = $2;
203  $$->next = $3;
204  }
205  | Assign NoneValue PairList {
206  if (0) {
207  $$ = (struct pair_t *) calloc (sizeof (struct pair_t), 1);
208  $$->key = $1;
209  $$->value = NULL;
210  $$->next = $3;
211  } else {
212  free ($1);
213  $$ = $3;
214  }
215  }
216 ;
218 /* A empty value in a pair list */
219 NoneValue: { /* nothing */ }
220  | '"' '"' { /* also nothing */ }
221 ;
222 
223 /* A property value, can either be on its own or enclosed in quotes */
224 Value:
225  PropertyValue {
226  $$ = $1;
227  }
228  | '"' PropertyValue '"' {
229  $$ = $2;
230  }
231 ;
232 
235  $$ = create_value ();
236  $$->value = $1;
237  }
238  | REAL ScaleOrUnit {
239  $$ = create_value ();
240  $$->value = $1;
241  $$->scale = $2;
242  }
244  $$ = create_value ();
245  $$->value = $1;
246  $$->scale = $2;
247  $$->unit = $3;
248  }
249 ;
252  PropertyReal {
253  $$ = $1;
254  }
256  $$ = create_value ();
257  $$->ident = $1;
258  }
259  | '[' InstanceIdentifier ']' {
260  $$ = create_value ();
261  $$->ident = $2;
262  }
263  | '[' ValueList ']' {
264  $$ = $2;
265  }
266 ;
267 
268 ValueList: /* nothing */ { $$ = NULL; }
270  $1->next = NULL;
271  $$ = $1;
272  }
274  $1->next = $3;
275  $$ = $1;
276  }
277 ;
280  Eqn ':' InstanceIdentifier Equation EquationList Eol {
281  /* create equation definition */
282  $$ = (struct definition_t *) calloc (sizeof (struct definition_t), 1);
283  $$->type = strdup ("Eqn");
284  $$->instance = $3;
285  $$->action = PROP_ACTION;
286  $$->line = netlist_lineno;
287  $4->setInstance ($3);
288  $4->setNext ($5);
289  $4->applyInstance ();
290  $$->eqns = $4;
291  }
292 ;
293 
294 EquationList: /* nothing */ { $$ = NULL; }
295  | Equation EquationList {
296  $1->setNext ($2);
297  $$ = $1;
298  }
299 ;
300 
301 Equation:
302  Assign '"' Expression '"' {
303  $$ = new eqn::assignment ();
304  $$->result = $1;
305  $$->body = $3;
306  }
307 ;
308 
309 Expression:
310  Constant {
311  $$ = $1;
312  }
314  $$ = $1;
315  }
317  $$ = $1;
318  }
319  | '(' Expression ')' {
320  $$ = $2;
321  }
322  | '[' Vector ']' {
323  $$ = $2;
324  }
325  | '[' Matrix ']' {
326  $$ = $2;
327  }
328 ;
330 ExpressionCol:
332  $1->appendNodes ($2);
333  $$ = $1;
334  }
335 ;
336 
337 ExpressionColList: /* nothing */ { $$ = NULL; }
339  $2->appendNodes ($3);
340  $$ = $2;
341  }
342 ;
343 
344 ExpressionVector:
345  ExpressionCol
346 ;
347 
348 Vector:
349  ExpressionVector {
350  $$ = new eqn::application ();
351  $$->n = strdup ("vector");
352  $$->nargs = $1->count ();
353  $$->args = $1;
354  }
355 ;
356 
357 ExpressionRowList: /* nothing */ { $$ = NULL; }
358  | ';' ExpressionCol ExpressionRowList {
359  eqn::constant * c = new eqn::constant (eqn::TAG_CHAR);
360  c->chr = ';';
361  c->appendNodes ($2);
362  $2->appendNodes ($3);
363  $$ = c;
364  }
365 ;
366 
367 ExpressionMatrix:
368  ExpressionCol ';' ExpressionCol ExpressionRowList {
369  eqn::constant * c = new eqn::constant (eqn::TAG_CHAR);
370  c->chr = ';';
371  c->appendNodes ($3);
372  $3->appendNodes ($4);
373  $1->appendNodes (c);
374  $$ = $1;
375  }
376 ;
377 
378 Matrix:
379  ExpressionMatrix {
380  $$ = new eqn::application ();
381  $$->n = strdup ("matrix");
382  $$->nargs = $1->count ();
383  $$->args = $1;
384  }
385 ;
386 
387 Constant:
388  REAL {
389  $$ = new eqn::constant (eqn::TAG_DOUBLE);
390  $$->d = $1;
391  }
392  | IMAG {
393  $$ = new eqn::constant (eqn::TAG_COMPLEX);
394  $$->c = new nr_complex_t (0.0, $1);
395  }
397  $$ = new eqn::constant (eqn::TAG_CHAR);
398  $$->chr = $1;
399  }
400  | STRING {
401  $$ = new eqn::constant (eqn::TAG_STRING);
402  $$->s = $1;
403  }
404 ;
405 
406 Range:
407  Expression ':' Expression {
408  $$ = new eqn::application ();
409  $$->n = strdup ("range");
410  $$->nargs = 2;
411  $1->append ($3);
412  $$->args = $1;
413  }
414  | ':' Expression {
415  $$ = new eqn::application ();
416  $$->n = strdup ("range");
417  $$->nargs = 2;
418  eqn::constant * c = new eqn::constant (eqn::TAG_CHAR);
419  c->chr = '?';
420  c->append ($2);
421  $$->args = c;
422  }
423  | Expression ':' {
424  $$ = new eqn::application ();
425  $$->n = strdup ("range");
426  $$->nargs = 2;
427  eqn::constant * c = new eqn::constant (eqn::TAG_CHAR);
428  c->chr = '?';
429  $1->append (c);
430  $$->args = $1;
431  }
432  | ':' {
433  $$ = new eqn::application ();
434  $$->n = strdup ("range");
435  $$->nargs = 2;
436  eqn::constant * c1 = new eqn::constant (eqn::TAG_CHAR);
437  eqn::constant * c2 = new eqn::constant (eqn::TAG_CHAR);
438  c1->chr = '?';
439  c2->chr = '?';
440  c1->append (c2);
441  $$->args = c1;
442  }
443 ;
444 
445 Reference:
446  Identifier {
447  $$ = new eqn::reference ();
448  $$->n = $1;
449  }
450 ;
451 
453  Identifier '(' ExpressionList ')' {
454  $$ = new eqn::application ();
455  $$->n = $1;
456  $$->nargs = $3->count ();
457  $$->args = $3;
458  }
459  | Reference '[' ExpressionList ']' {
460  $$ = new eqn::application ();
461  $$->n = strdup ("array");
462  $$->nargs = 1 + $3->count ();
463  $1->setNext ($3);
464  $$->args = $1;
465  }
466  | Expression '+' Expression {
467  $$ = new eqn::application ();
468  $$->n = strdup ("+");
469  $$->nargs = 2;
470  $1->append ($3);
471  $$->args = $1;
472  }
473  | Expression '-' Expression {
474  $$ = new eqn::application ();
475  $$->n = strdup ("-");
476  $$->nargs = 2;
477  $1->append ($3);
478  $$->args = $1;
479  }
480  | Expression '*' Expression {
481  $$ = new eqn::application ();
482  $$->n = strdup ("*");
483  $$->nargs = 2;
484  $1->append ($3);
485  $$->args = $1;
486  }
487  | Expression '/' Expression {
488  $$ = new eqn::application ();
489  $$->n = strdup ("/");
490  $$->nargs = 2;
491  $1->append ($3);
492  $$->args = $1;
493  }
494  | Expression '%' Expression {
495  $$ = new eqn::application ();
496  $$->n = strdup ("%");
497  $$->nargs = 2;
498  $1->append ($3);
499  $$->args = $1;
500  }
501  | '+' Expression %prec POS {
502  $$ = new eqn::application ();
503  $$->n = strdup ("+");
504  $$->nargs = 1;
505  $$->args = $2;
506  }
507  | '-' Expression %prec NEG {
508  $$ = new eqn::application ();
509  $$->n = strdup ("-");
510  $$->nargs = 1;
511  $$->args = $2;
512  }
513  | Expression '^' Expression {
514  $$ = new eqn::application ();
515  $$->n = strdup ("^");
516  $$->nargs = 2;
517  $1->append ($3);
518  $$->args = $1;
519  }
520  | Expression '?' Expression ':' Expression {
521  $$ = new eqn::application ();
522  $$->n = strdup ("?:");
523  $$->nargs = 3;
524  $1->append ($3);
525  $1->append ($5);
526  $$->args = $1;
527  }
528  | Expression Less Expression {
529  $$ = new eqn::application ();
530  $$->n = strdup ("<");
531  $$->nargs = 2;
532  $1->append ($3);
533  $$->args = $1;
534  }
535  | Expression Greater Expression {
536  $$ = new eqn::application ();
537  $$->n = strdup (">");
538  $$->nargs = 2;
539  $1->append ($3);
540  $$->args = $1;
541  }
542  | Expression GreaterOrEqual Expression {
543  $$ = new eqn::application ();
544  $$->n = strdup (">=");
545  $$->nargs = 2;
546  $1->append ($3);
547  $$->args = $1;
548  }
549  | Expression LessOrEqual Expression {
550  $$ = new eqn::application ();
551  $$->n = strdup ("<=");
552  $$->nargs = 2;
553  $1->append ($3);
554  $$->args = $1;
555  }
556  | Expression Equal Expression {
557  $$ = new eqn::application ();
558  $$->n = strdup ("==");
559  $$->nargs = 2;
560  $1->append ($3);
561  $$->args = $1;
562  }
563  | Expression NotEqual Expression {
564  $$ = new eqn::application ();
565  $$->n = strdup ("!=");
566  $$->nargs = 2;
567  $1->append ($3);
568  $$->args = $1;
569  }
570  | Not Expression {
571  $$ = new eqn::application ();
572  $$->n = strdup ("!");
573  $$->nargs = 1;
574  $$->args = $2;
575  }
576  | Expression And Expression {
577  $$ = new eqn::application ();
578  $$->n = strdup ("&&");
579  $$->nargs = 2;
580  $1->append ($3);
581  $$->args = $1;
582  }
583  | Expression Or Expression {
584  $$ = new eqn::application ();
585  $$->n = strdup ("||");
586  $$->nargs = 2;
587  $1->append ($3);
588  $$->args = $1;
589  }
590 ;
591 
592 ExpressionList: /* nothing */ { $$ = NULL; }
593  | Expression {
594  $$ = $1;
595  }
596  | Range {
597  $$ = $1;
598  }
600  $1->setNext ($3);
601  $$ = $1;
602  }
603  | Range ',' ExpressionList {
604  $1->setNext ($3);
605  $$ = $1;
606  }
607 ;
608 
610  DefBegin DefBody DefEnd { /* a full subcircuit definition found */
611  $1->sub = $2;
612  $$ = $1;
613  $2 = NULL;
614  }
615 ;
616 
617 DefBegin:
619  /* create subcircuit definition right here */
620  $$ = (struct definition_t *) calloc (sizeof (struct definition_t), 1);
621  $$->type = strdup ("Def");
622  $$->instance = $2;
623  $$->nodes = $3;
624  $$->pairs = $4;
625  $$->action = PROP_ACTION;
626  $$->line = netlist_lineno;
627  }
628 ;
629 
630 DefBody: /* nothing */ { $$ = NULL; }
631  | DefBodyLine DefBody { /* chain definitions here */
632  if ($1) {
633  $1->next = $2;
634  $$ = $1;
635  }
636  else {
637  $$ = $2;
638  }
639  }
640 ;
641 
642 DefEnd:
643  EndSub Eol { /* nothing to do */ }
644 ;
645 
646 DefBodyLine:
647  DefinitionLine { /* chain definitions here */
648  $1->next = $$;
649  $$ = $1;
650  }
651  | EquationLine { /* chain definitions here */
652  $1->next = $$;
653  $$ = $1;
654  }
655  | SubcircuitBody { /* do nothing here, see subcircuit rule */ }
656  | Eol {
657  $$ = NULL;
658  }
659 ;
660 
661 
662 %%
663 
664 int netlist_error (const char * error) {
665  logprint (LOG_ERROR, "line %d: %s\n", netlist_lineno, error);
666  return 0;
667 }
std::complex< nr_double_t > nr_complex_t
Definition: complex.h:31
Assign Value PairList
Definition: netdefs.h:33
SubcircuitBody
name
Definition: parse_mdl.y:352
InstanceIdentifier
value
Character
Identifier
Definition: parse_csv.y:87
PropertyReal
Expression
double r
Definition: check_mdl.h:59
ExpressionList
Definition: netdefs.h:54
DefBodyLine DefBody
ExpressionCol ExpressionRowList
Expression ExpressionColList
NodeIdentifier NodeList
Application
IMAG
free($1)
< INITIAL >< INITIAL >< INITIAL >< INITIAL > return InvalidCharacter
Definition: scan_netlist.l:698
eqn::constant * c1
eqn::constant * c2
STRING
char * subcircuit
Definition: netdefs.h:79
ident
InputLine InputList
EquationLine
Equation EquationList
DefinitionLine
Definition: parse_spice.y:206
int netlist_lineno
Definition: parse_netlist.y:36
struct definition_t * definition_root
Reference
double i
Definition: check_mdl.h:60
ValueList
ScaleOrUnit
c chr
Range
#define LOG_ERROR
Definition: logging.h:28
node
int netlist_error(const char *error)
#define PROP_COMPONENT
Expression prec POS
Expression prec NEG
void logprint(int level, const char *format,...)
Definition: logging.c:37
REAL
Definition: parse_vcd.y:236
name prefix
Definition: parse_netlist.y:49
EquationLine ActionLine DefinitionLine Eol
#define create_value()
#define PROP_ACTION
PropertyValue