Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
scan_netlist.l
Go to the documentation of this file.
1 /* -*-c-*- */
2 
3 %{
4 /*
5  * scan_netlist.l - scanner for the Qucs netlist
6  *
7  * Copyright (C) 2003-2009 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 #include <ctype.h>
36 
37 #ifdef __MINGW32__
38 #include <io.h>
39 #endif
40 
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 
45 #include "logging.h"
46 #include "equation.h"
47 #include "check_netlist.h"
48 #include "tokens_netlist.h"
49 
50 #if !HAVE_STRCHR
51 # define strchr index
52 # define strrchr rindex
53 #endif
54 
55 using namespace qucs;
56 
57 static double netlist_evaluate_scale (double val, char * scale) {
58  double factor = 1.0;
59  while (isspace (scale[0])) scale++;
60  switch (scale[0]) {
61  case 'E': factor = 1e+18; break;
62  case 'P': factor = 1e+15; break;
63  case 'T': factor = 1e+12; break;
64  case 'G': factor = 1e+09; break;
65  case 'M': factor = 1e+06; break;
66  case 'k': factor = 1e+03; break;
67  case 'm':
68  if (scale[1] == 'i' && scale[2] == 'l')
69  factor = 2.54e-5;
70  else
71  factor = 1e-03;
72  break;
73  case 'u': factor = 1e-06; break;
74  case 'n': factor = 1e-09; break;
75  case 'p': factor = 1e-12; break;
76  case 'f':
77  if (scale[1] == 't')
78  factor = 0.3048;
79  else
80  factor = 1e-15;
81  break;
82  case 'a': factor = 1e-18; break;
83  case 'd':
84  if (scale[1] == 'B') {
85  val = std::pow (10.0, val / 10.0);
86  if (scale[2] == 'm')
87  factor = 1e-03;
88  else if (scale[2] == 'u')
89  factor = 1e-06;
90  }
91  break;
92  case 'i':
93  if (scale[1] == 'n')
94  factor = 2.54e-2;
95  break;
96  case 'y':
97  if (scale[1] == 'd')
98  factor = 0.9144;
99  break;
100  }
101  return val * factor;
102 }
103 
104 %}
105 
106 WS [ \t\n\r]
107 SIMPLEID [a-zA-Z_][a-zA-Z0-9_]*
108 POSTID "."[a-zA-Z0-9_]+
109 ID {SIMPLEID}{POSTID}*
110 NODE {SIMPLEID}\!?
111 FILE "{"[^\t\n\r\}]+"}"
112 CHR "'"[^\n\r\']{1}"'"
113 STR "'"[^\n\r\']*"'"
114 DIGIT [0-9]
115 EXPONENT [Ee][+-]?{DIGIT}+
116 PFX1 ("E"|"P"|"T"|"G"|"M"|"k"|"m"|"u"|"n"|"p"|"f"|"a")
117 PFX2 ("mil"|"in"|"ft"|"yd")
118 PFX3 ("dBu"|"dBm"|"dB")
119 PFX ({PFX1}|{PFX3})
120 UNT ("Ohm"|"S"|"s"|"K"|"H"|"F"|"Hz"|"V"|"A"|"W"|"m")
121 EXCEPT ("mm"|{PFX2})
122 SU ({PFX}|{UNT}|{PFX}{UNT}|{EXCEPT})
123 SPACE [ \t]
124 RINT [+-]?{DIGIT}+
125 IINT [+-]?[ij]{1}{DIGIT}*
126 RFLOAT1 [+-]?{DIGIT}+{EXPONENT}
127 RFLOAT2 [+-]?{DIGIT}*"."{DIGIT}+({EXPONENT})?
128 IFLOAT1 [+-]?[ij]{1}{DIGIT}+{EXPONENT}
129 IFLOAT2 [+-]?[ij]{1}{DIGIT}*"."{DIGIT}+({EXPONENT})?
130 CREAL ({RFLOAT1}|{RFLOAT2}|{RINT})
131 CIMAG ({IFLOAT1}|{IFLOAT2}|{IINT})
132 COMPLEX {CREAL}{CIMAG}
133 URINT {DIGIT}+
134 UIINT [ij]{1}{DIGIT}*
135 URFLOAT1 {DIGIT}+{EXPONENT}
136 URFLOAT2 {DIGIT}*"."{DIGIT}+({EXPONENT})?
137 UIFLOAT1 [ij]{1}{DIGIT}+{EXPONENT}
138 UIFLOAT2 [ij]{1}{DIGIT}*"."{DIGIT}+({EXPONENT})?
139 UCREAL ({URFLOAT1}|{URFLOAT2}|{URINT})({SPACE})*({PFX})?
140 UCIMAG ({UIFLOAT1}|{UIFLOAT2}|{UIINT})({SPACE})*({PFX})?
141 UCOMPLEX {UCREAL}{UCIMAG}
142 
143 
144 %x COMMENT STR EQN
145 %option yylineno noyywrap nounput prefix="netlist_"
146 
147 %%
148 
149 <INITIAL,STR>{SU} { /* identify scale and/or unit */
150  netlist_lval.str = strdup (netlist_text);
151  return ScaleOrUnit;
152  }
153 <INITIAL>"Eqn" { /* special equation case */
154  BEGIN(EQN);
155  return Eqn;
156  }
157 <INITIAL>"."{SPACE}*"Def"{SPACE}*":" {
158  /* subcircuit definition begins */
159  return DefSub;
160  }
161 <INITIAL>"."{SPACE}*"Def"{SPACE}*":"{SPACE}*"End" {
162  /* subcircuit definition ends */
163  return EndSub;
164  }
165 <INITIAL,STR>{ID} { /* identify identifier */
166  netlist_lval.ident = strdup (netlist_text);
167  return Identifier;
168  }
169 <INITIAL>{NODE} { /* identify node identifier */
170  netlist_lval.ident = strdup (netlist_text);
171  return Identifier;
172  }
173 <INITIAL,STR>{FILE} { /* identify file reference */
174  char * p = strrchr (netlist_text, '}'); *p = '\0';
175  netlist_lval.ident = strdup (&netlist_text[1]);
176  return Identifier;
177  }
178 <INITIAL,STR>{CREAL} { /* identify (signed) real float */
179  netlist_lval.d = strtod (netlist_text, NULL);
180  return REAL;
181  }
182 <INITIAL,STR>{CIMAG} { /* identify (signed) imaginary float */
183  if (netlist_text[0] == 'i' || netlist_text[0] == 'j')
184  netlist_text[0] = (netlist_text[1] == '\0') ? '1' : '0';
185  else
186  netlist_text[1] = '0';
187  netlist_lval.d = strtod (netlist_text, NULL);
188  return IMAG;
189  }
190 <INITIAL,STR>{COMPLEX} { /* identify complete (signed) complex number */
191  int i = 0;
192  while (netlist_text[i] != 'i' && netlist_text[i] != 'j') i++;
193  netlist_text[i] = netlist_text[i - 1];
194  netlist_text[i - 1] = '\0';
195  netlist_lval.c.r = strtod (netlist_text, NULL);
196  netlist_lval.c.i = strtod (&netlist_text[i], NULL);
197  return COMPLEX;
198  }
199 <INITIAL,EQN>{ID}{SPACE}*=[^=] { /* identify 'identifier =' assign */
200  int len = netlist_leng - 3;
201  while (isspace (netlist_text[len])) len--;
202  netlist_lval.ident = (char *) calloc (len + 2, 1);
203  memcpy (netlist_lval.ident, netlist_text, len + 1);
204  yyless (netlist_leng - 1); /* push back last character */
205  return Assign;
206  }
207 
208 <INITIAL,STR>"[" { /* special token for the value list */ return '['; }
209 <INITIAL,STR>"]" { /* special token for the value list */ return ']'; }
210 <INITIAL,STR>";" { /* special token for the value list */ return ';'; }
211 
212 <INITIAL>"." { /* pass the '.' to the parser */ return '.'; }
213 <INITIAL>":" { /* pass the ':' to the parser */ return ':'; }
214 <INITIAL>"=" { /* pass the '=' to the parser */ return '='; }
215 <INITIAL>\r?\n { /* detect end of line */ return Eol; }
216 
217 <INITIAL,EQN>{SPACE}|\\\r?\n /* skip spaces and the trailing '\' */
218 
219 <INITIAL>"#" { /* leave these characters */
220  BEGIN(COMMENT);
221  }
222 <INITIAL>\" { /* string constant starts here */
223  BEGIN(STR);
224  return '"';
225  }
226 <INITIAL>. { /* any other character in invalid */
227  logprint (LOG_ERROR,
228  "line %d: syntax error, unrecognized character: `%s'\n",
229  netlist_lineno, netlist_text);
230  return InvalidCharacter;
231  }
232 
233 <COMMENT>. { /* skip any character in here */ }
234 <COMMENT>\r?\n { BEGIN(INITIAL); /* skipping ends here */ }
235 
236 <STR>\" { /* string constant ends here */
237  BEGIN(INITIAL);
238  return '"';
239  }
240 <STR>\r?\n { /* string in a single line only */
241  logprint (LOG_ERROR,
242  "line %d: syntax error, unterminated string constant\n",
243  netlist_lineno);
244  return Eol;
245  }
246 <STR,EQN>{SPACE} /* skip spaces */
247 
248 <STR>. { /* any other character is invalid */
249  logprint (LOG_ERROR,
250  "line %d: syntax error, unrecognized character: `%s'\n",
251  netlist_lineno, netlist_text);
252  return InvalidCharacter;
253  }
254 
255 <EQN>[-+*/%(),^:\"\[\]\?] { /* return operators unchanged */
256  return netlist_text[0];
257  }
258 
259 <EQN>">=" { return GreaterOrEqual; }
260 <EQN>"<=" { return LessOrEqual; }
261 <EQN>"!=" { return NotEqual; }
262 <EQN>"==" { return Equal; }
263 <EQN>"&&" { return And; }
264 <EQN>"||" { return Or; }
265 <EQN>"<" { return Less; }
266 <EQN>">" { return Greater; }
267 <EQN>"!" { return Not; }
268 
269 <EQN>[,;] { /* special tokens for vectors / matrices */
270  return netlist_text[0];
271  }
272 
273 <EQN>{UCREAL} { /* identify unsigned real float */
274  char * endptr = NULL;
275  netlist_lval.d = strtod (netlist_text, &endptr);
276  netlist_lval.d = netlist_evaluate_scale (netlist_lval.d, endptr);
277  return REAL;
278  }
279 <EQN>{UCIMAG} { /* identify unsigned imaginary float */
280  if (netlist_text[0] == 'i' || netlist_text[0] == 'j')
281  netlist_text[0] = (netlist_text[1] == '\0') ? '1' : '0';
282  else
283  netlist_text[1] = '0';
284  char * endptr = NULL;
285  netlist_lval.d = strtod (netlist_text, &endptr);
286  netlist_lval.d = netlist_evaluate_scale (netlist_lval.d, endptr);
287  return IMAG;
288  }
289 <EQN>{ID} { /* identify identifier */
290  netlist_lval.ident = strdup (netlist_text);
291  return Identifier;
292  }
293 <EQN>{CHR} {
294  netlist_lval.chr = netlist_text[1];
295  return Character;
296  }
297 <EQN>{STR} {
298  netlist_lval.str = strdup (&netlist_text[1]);
299  netlist_lval.str[strlen (netlist_lval.str) - 1] = '\0';
300  return STRING;
301  }
302 <EQN>\r?\n { /* detect end of line */ BEGIN(INITIAL); return Eol; }
303 
304 <EQN>. { /* any other character in invalid */
305  logprint (LOG_ERROR,
306  "line %d: syntax error, unrecognized character: `%s'\n",
307  netlist_lineno, netlist_text);
308  return InvalidCharacter;
309  }
310 
311 %%
nr_complex_t pow(const nr_complex_t z, const nr_double_t d)
Compute power function with real exponent.
Definition: complex.cpp:238
#define E(equ)
Definition: parasweep.cpp:81
#define K
Absolute 0 in centigrade.
Definition: constants.h:59
#define S(con)
Definition: property.cpp:158
r
Definition: parse_mdl.y:515
nr_double_t dB(const nr_complex_t z)
Magnitude in dB Compute .
Definition: complex.cpp:528
#define V(con)
Definition: evaluate.cpp:63
#define Z_(r, c)
Definition: hbsolver.cpp:689
static double netlist_evaluate_scale(double val, char *scale)
Definition: scan_netlist.l:529
WS[\t\n\r] SIMPLEID *[a-zA-Z_][a-zA-Z0-9_] POSTID[a-zA-Z0-9_] ID
Definition: scan_netlist.l:581
#define A(a)
Definition: eqndefined.cpp:72
#define CHR(con)
Definition: evaluate.cpp:67
vcd scale
Definition: parse_vcd.y:180
#define M(con)
Definition: evaluate.cpp:64
#define Z0
Wave impedance in vacuum ( )
Definition: constants.h:53
< COMMENT >< STR > r n
Definition: scan_netlist.l:712
line