LCOV - code coverage report
Current view: top level - src - scan_netlist.l (source / functions) Hit Total Coverage
Test: qucs-core-0.0.19 Code Coverage Lines: 47 126 37.3 %
Date: 2015-01-05 16:01:02 Functions: 1 1 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 9 62 14.5 %

           Branch data     Line data    Source code
       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                 :        141 : static double netlist_evaluate_scale (double val, char * scale) {
      58                 :        141 :   double factor = 1.0;
      59         [ +  + ]:        145 :   while (isspace (scale[0])) scale++;
      60   [ -  -  -  -  :        141 :   switch (scale[0]) {
          -  +  -  -  -  
          -  -  -  -  -  
                   -  + ]
      61                 :          0 :   case 'E': factor = 1e+18; break;
      62                 :          0 :   case 'P': factor = 1e+15; break;
      63                 :          0 :   case 'T': factor = 1e+12; break;
      64                 :          0 :   case 'G': factor = 1e+09; break;
      65                 :          0 :   case 'M': factor = 1e+06; break;
      66                 :          3 :   case 'k': factor = 1e+03; break;
      67                 :            :   case 'm':
      68 [ #  # ][ #  # ]:          0 :     if (scale[1] == 'i' && scale[2] == 'l')
      69                 :          0 :       factor = 2.54e-5;
      70                 :            :     else
      71                 :          0 :       factor = 1e-03;
      72                 :          0 :     break;
      73                 :          0 :   case 'u': factor = 1e-06; break;
      74                 :          0 :   case 'n': factor = 1e-09; break;
      75                 :          0 :   case 'p': factor = 1e-12; break;
      76                 :            :   case 'f':
      77         [ #  # ]:          0 :     if (scale[1] == 't')
      78                 :          0 :       factor = 0.3048;
      79                 :            :     else
      80                 :          0 :       factor = 1e-15;
      81                 :          0 :     break;
      82                 :          0 :   case 'a': factor = 1e-18; break;
      83                 :            :   case 'd':
      84         [ #  # ]:          0 :     if (scale[1] == 'B') {
      85                 :          0 :       val = std::pow (10.0, val / 10.0);
      86         [ #  # ]:          0 :       if (scale[2] == 'm')
      87                 :          0 :         factor = 1e-03;
      88         [ #  # ]:          0 :       else if (scale[2] == 'u')
      89                 :          0 :         factor = 1e-06;
      90                 :            :     }
      91                 :          0 :     break;
      92                 :            :   case 'i':
      93         [ #  # ]:          0 :     if (scale[1] == 'n')
      94                 :          0 :       factor = 2.54e-2;
      95                 :          0 :     break;
      96                 :            :   case 'y':
      97         [ #  # ]:          0 :     if (scale[1] == 'd')
      98                 :          0 :       factor = 0.9144;
      99                 :          0 :     break;
     100                 :            :   }
     101                 :        141 :   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                 :       1679 :     netlist_lval.str = strdup (netlist_text);
     151                 :       1679 :     return ScaleOrUnit;
     152                 :            :   }
     153                 :            : <INITIAL>"Eqn" { /* special equation case */
     154                 :         68 :     BEGIN(EQN);
     155                 :         68 :     return Eqn;
     156                 :            :   }
     157                 :            : <INITIAL>"."{SPACE}*"Def"{SPACE}*":" {
     158                 :            :     /* subcircuit definition begins */
     159                 :         13 :     return DefSub;
     160                 :            :   }
     161                 :            : <INITIAL>"."{SPACE}*"Def"{SPACE}*":"{SPACE}*"End" {
     162                 :            :     /* subcircuit definition ends */
     163                 :         13 :     return EndSub;
     164                 :            :   }
     165                 :            : <INITIAL,STR>{ID} { /* identify identifier */
     166                 :       5219 :     netlist_lval.ident = strdup (netlist_text);
     167                 :       5219 :     return Identifier;
     168                 :            :   }
     169                 :            : <INITIAL>{NODE} { /* identify node identifier */
     170                 :          0 :     netlist_lval.ident = strdup (netlist_text);
     171                 :          0 :     return Identifier;
     172                 :            :   }
     173                 :            : <INITIAL,STR>{FILE} { /* identify file reference */
     174                 :          0 :     char * p = strrchr (netlist_text, '}'); *p = '\0';
     175                 :          0 :     netlist_lval.ident = strdup (&netlist_text[1]);
     176                 :          0 :     return Identifier;
     177                 :            :   }
     178                 :            : <INITIAL,STR>{CREAL} { /* identify (signed) real float */
     179                 :       9232 :     netlist_lval.d = strtod (netlist_text, NULL);
     180                 :       9232 :     return REAL;
     181                 :            :   }
     182                 :            : <INITIAL,STR>{CIMAG} { /* identify (signed) imaginary float */
     183 [ #  # ][ #  # ]:          0 :     if (netlist_text[0] == 'i' || netlist_text[0] == 'j')
     184         [ #  # ]:          0 :       netlist_text[0] = (netlist_text[1] == '\0') ? '1' : '0';
     185                 :            :     else
     186                 :          0 :       netlist_text[1] = '0';
     187                 :          0 :     netlist_lval.d = strtod (netlist_text, NULL);
     188                 :          0 :     return IMAG;
     189                 :            :   }
     190                 :            : <INITIAL,STR>{COMPLEX} { /* identify complete (signed) complex number */
     191                 :          0 :     int i = 0;
     192 [ #  # ][ #  # ]:          0 :     while (netlist_text[i] != 'i' && netlist_text[i] != 'j') i++;
                 [ #  # ]
     193                 :          0 :     netlist_text[i] = netlist_text[i - 1];
     194                 :          0 :     netlist_text[i - 1] = '\0';
     195                 :          0 :     netlist_lval.c.r = strtod (netlist_text, NULL);
     196                 :          0 :     netlist_lval.c.i = strtod (&netlist_text[i], NULL);
     197                 :          0 :     return COMPLEX;
     198                 :            :   }
     199                 :            : <INITIAL,EQN>{ID}{SPACE}*=[^=] {  /* identify 'identifier =' assign */
     200                 :      10506 :     int len = netlist_leng - 3;
     201         [ -  + ]:      10506 :     while (isspace (netlist_text[len])) len--;
     202                 :      10506 :     netlist_lval.ident = (char *) calloc (len + 2, 1);
     203                 :      10506 :     memcpy (netlist_lval.ident, netlist_text, len + 1);
     204 [ -  + ][ +  + ]:      21012 :     yyless (netlist_leng - 1); /* push back last character */
     205                 :      10506 :     return Assign;
     206                 :            :   }
     207                 :            : 
     208                 :          6 : <INITIAL,STR>"[" { /* special token for the value list */ return '['; }
     209                 :          6 : <INITIAL,STR>"]" { /* special token for the value list */ return ']'; }
     210                 :         12 : <INITIAL,STR>";" { /* special token for the value list */ return ';'; }
     211                 :            : 
     212                 :        181 : <INITIAL>"."   { /* pass the '.' to the parser */ return '.'; }
     213                 :       1085 : <INITIAL>":"   { /* pass the ':' to the parser */ return ':'; }
     214                 :          0 : <INITIAL>"="   { /* pass the '=' to the parser */ return '='; }
     215                 :       1232 : <INITIAL>\r?\n { /* detect end of line */ return Eol; }
     216                 :            : 
     217                 :            : <INITIAL,EQN>{SPACE}|\\\r?\n /* skip spaces and the trailing '\' */
     218                 :      12782 : 
     219                 :            : <INITIAL>"#" { /* leave these characters */
     220                 :        103 :     BEGIN(COMMENT);
     221                 :            :   }
     222                 :        103 : <INITIAL>\" { /* string constant starts here */
     223                 :      10299 :     BEGIN(STR);
     224                 :      10299 :     return '"';
     225                 :            :   }
     226                 :            : <INITIAL>. { /* any other character in invalid */
     227                 :            :     logprint (LOG_ERROR,
     228                 :            :               "line %d: syntax error, unrecognized character: `%s'\n",
     229                 :          0 :               netlist_lineno, netlist_text);
     230                 :          0 :     return InvalidCharacter;
     231                 :            :   }
     232                 :            : 
     233                 :            : <COMMENT>. { /* skip any character in here */ }
     234                 :       8580 : <COMMENT>\r?\n { BEGIN(INITIAL); /* skipping ends here */ }
     235                 :        103 : 
     236                 :            : <STR>\" { /* string constant ends here */
     237                 :      10299 :     BEGIN(INITIAL);
     238                 :      10299 :     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                 :          0 :               netlist_lineno);
     244                 :          0 :     return Eol;
     245                 :            :   }
     246                 :            : <STR,EQN>{SPACE} /* skip spaces */
     247                 :       1329 : 
     248                 :            : <STR>. { /* any other character is invalid */
     249                 :            :     logprint (LOG_ERROR,
     250                 :            :               "line %d: syntax error, unrecognized character: `%s'\n",
     251                 :          0 :               netlist_lineno, netlist_text);
     252                 :          0 :     return InvalidCharacter;
     253                 :            :   }
     254                 :            : 
     255                 :            : <EQN>[-+*/%(),^:\"\[\]\?] { /* return operators unchanged */
     256                 :        950 :     return netlist_text[0];
     257                 :            :   }
     258                 :            : 
     259                 :          0 : <EQN>">=" { return GreaterOrEqual; }
     260                 :          0 : <EQN>"<=" { return LessOrEqual; }
     261                 :          0 : <EQN>"!=" { return NotEqual; }
     262                 :          0 : <EQN>"==" { return Equal; }
     263                 :          0 : <EQN>"&&" { return And; }
     264                 :          0 : <EQN>"||" { return Or; }
     265                 :         21 : <EQN>"<"  { return Less; }
     266                 :          0 : <EQN>">"  { return Greater; }
     267                 :          0 : <EQN>"!"  { return Not; }
     268                 :            : 
     269                 :            : <EQN>[,;] { /* special tokens for vectors / matrices */
     270                 :          0 :     return netlist_text[0];
     271                 :            :   }
     272                 :            : 
     273                 :            : <EQN>{UCREAL} { /* identify unsigned real float */
     274                 :        141 :     char * endptr = NULL;
     275                 :        141 :     netlist_lval.d = strtod (netlist_text, &endptr);
     276         [ +  - ]:        141 :     netlist_lval.d = netlist_evaluate_scale (netlist_lval.d, endptr);
     277                 :        141 :     return REAL;
     278                 :            :   }
     279                 :            : <EQN>{UCIMAG} { /* identify unsigned imaginary float */
     280 [ #  # ][ #  # ]:          0 :     if (netlist_text[0] == 'i' || netlist_text[0] == 'j')
     281         [ #  # ]:          0 :       netlist_text[0] = (netlist_text[1] == '\0') ? '1' : '0';
     282                 :            :     else
     283                 :          0 :       netlist_text[1] = '0';
     284                 :          0 :     char * endptr = NULL;
     285                 :          0 :     netlist_lval.d = strtod (netlist_text, &endptr);
     286         [ #  # ]:          0 :     netlist_lval.d = netlist_evaluate_scale (netlist_lval.d, endptr);
     287                 :          0 :     return IMAG;
     288                 :            :   }
     289                 :            : <EQN>{ID} { /* identify identifier */
     290                 :        442 :     netlist_lval.ident = strdup (netlist_text);
     291                 :        442 :     return Identifier;
     292                 :            :   }
     293                 :            : <EQN>{CHR} {
     294                 :          0 :     netlist_lval.chr = netlist_text[1];
     295                 :          0 :     return Character;
     296                 :            :   }
     297                 :            : <EQN>{STR} {
     298                 :          0 :     netlist_lval.str = strdup (&netlist_text[1]);
     299                 :          0 :     netlist_lval.str[strlen (netlist_lval.str) - 1] = '\0';
     300                 :          0 :     return STRING;
     301                 :            :   }
     302                 :         68 : <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                 :          0 :               netlist_lineno, netlist_text);
     308                 :          0 :     return InvalidCharacter;
     309                 :            :   }
     310                 :            : 
     311                 :          0 : %%

Generated by: LCOV version 1.11