Skip to content

Commit

Permalink
Fix build issues flex/bison part
Browse files Browse the repository at this point in the history
-fixed deprecated yacc/bison name-prefix directive warning, shift/reduce-conflicts (sr) and
 reduce/reduce-conflicts (rr) of the spice-parser build by parse_spice.ypp and scan_spice.lpp:
   -sr-conflicts solved by introducing token/rule precedence
   -rr-conflicts solved by introducing token lookahead's in the spice scanner
   -verification of equalness of generated output from both the converter before and
    after the code change done with spice input bjt.cir done
-fixed ra3xdh/qucs_s#967:
   -The lookahead-pattern for differentiate the 3-/4-/5-node spice-bjt
    erroneously contains newline. This causes read a spice bjt-line don't
    stop at new line and detect a 5-node bjt instead of 3-node bjt as
    happen for AD822X.cir of Opamp_AC_Tran.zip from the issue 967.
    This is fixed and tested against AD822X.cir. The critical lines from
    AD822X.cir are included in the bjt.cir qucsconv_rf testing example.

Signed-off-by: ThomasZecha <[email protected]>
  • Loading branch information
ThomasZecha committed Oct 22, 2024
1 parent abeec88 commit cdf2767
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 21 deletions.
37 changes: 25 additions & 12 deletions src/converter/parse_spice.ypp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@

#include "check_spice.h"

#define YY_HEADER_EXPORT_START_CONDITIONS
#include "scan_spice.hpp"

extern char* spice_text;

extern void push_state(int state);
extern void pop_state();

// Converts the given string into upper case.
static char * spice_toupper (char * str) {
for (unsigned int i = 0; i < strlen (str); i++) {
Expand Down Expand Up @@ -128,10 +136,11 @@ static struct value_t * spice_append_val_values (struct value_t * values,

%}

%name-prefix "spice_"
%define api.prefix {spice_}

%token TitleLine InvalidCharacter End Eol
%token Identifier Digits Floats Nodes Options Function
%token Identifier Digits Floats Nodes Options Function Lookahead_Double_Value
%token Lookahead_Three_Node Lookahead_Four_Node Lookahead_Five_Node
%token SUBCKT_Action ENDS_Action AC_Action OP_Action I_Source SAVE_Action
%token RLC_Device L_Device K_Device IV_Source GE_Source FH_Source V_Source
%token Diode_Device Bipolar_Device JFET_Device MOSFET_Device MESFET_Device
Expand All @@ -143,6 +152,9 @@ static struct value_t * spice_append_val_values (struct value_t * values,
%token U_Device S_Device W_Device ON_Special TF_Action SENS_Action FOUR_Action
%token OpFunc Behave TC_Special TEMP_Action

%precedence Identifier Digits Nodes
%precedence _NODE_

%union {
char * ident;
char * str;
Expand All @@ -162,7 +174,7 @@ static struct value_t * spice_append_val_values (struct value_t * values,
%type <value> IC_Condition_4 SWITCH_State NodeValueList TC_Value_1 TC_Value_2
%type <value> VSourceList

%type <ident> Identifier Nodes Function Value Floats Digits Node FH_Node
%type <ident> Identifier Nodes Function Value Lookahead_Double_Value Floats Digits Node FH_Node
%type <ident> RLC_Device K_Device L_Device IV_Source GE_Source FH_Source
%type <ident> V_Source MODEL_Spec Diode_Device Bipolar_Device JFET_Device
%type <ident> MOSFET_Device MESFET_Device TRAN_Action PLOT_Action MODEL_Action
Expand All @@ -174,7 +186,7 @@ static struct value_t * spice_append_val_values (struct value_t * values,
%type <ident> IC_Special OFF_Special SIM_Type TEMP_Special MOS_Special
%type <ident> BranchFunc NODESET_Action T_Device U_Device S_Device W_Device
%type <ident> TF_Action SENS_Action FOUR_Action OpFunc TC_Special TEMP_Action
%type <ident> Behave
%type <ident> Behave Lookahead_Three_Node Lookahead_Four_Node Lookahead_Five_Node

%%

Expand Down Expand Up @@ -374,7 +386,7 @@ DefinitionLine:
spice_append_str_value ($$, $5, HINT_NAME);
$$->values = netlist_append_values ($$->values, $6);
}
| Bipolar_Device Node Node Node MODEL_Ident DEVICE_List_2 {
| Bipolar_Device Lookahead_Three_Node Node Node MODEL_Ident DEVICE_List_2 {
/* 3 node BJT */
$$ = spice_create_device ($1);
spice_append_str_value ($$, $2, HINT_NODE);
Expand All @@ -383,7 +395,7 @@ DefinitionLine:
spice_append_str_value ($$, $5, HINT_NAME);
$$->values = netlist_append_values ($$->values, $6);
}
| Bipolar_Device Node Node Node Node MODEL_Ident DEVICE_List_2 {
| Bipolar_Device Lookahead_Four_Node Node Node Node MODEL_Ident DEVICE_List_2 {
/* 4 node BJT */
$$ = spice_create_device ($1);
spice_append_str_value ($$, $2, HINT_NODE);
Expand All @@ -393,7 +405,7 @@ DefinitionLine:
spice_append_str_value ($$, $6, HINT_NAME);
$$->values = netlist_append_values ($$->values, $7);
}
| Bipolar_Device Node Node Node Node Node MODEL_Ident DEVICE_List_2 {
| Bipolar_Device Lookahead_Five_Node Node Node Node Node MODEL_Ident DEVICE_List_2 {
/* 5 node BJT */
$$ = spice_create_device ($1);
spice_append_str_value ($$, $2, HINT_NODE);
Expand Down Expand Up @@ -661,21 +673,22 @@ IC_Condition_4:
;

Output_Range:
Value Value { /* range specification during plotting */
Lookahead_Double_Value Value { /* range specification during plotting */
$$ = NULL;
$$ = spice_append_val_values ($$, $1, HINT_NUMBER);
$$ = spice_append_val_values ($$, $2, HINT_NUMBER);
}
;

VOLTAGE_Output:
Node { // TODO: 2 reduce/reduce, 2 shift/reduce
Node {
/* print/plot specification of node voltage */
push_state(DOUBLEVALUE);
$$ = NULL;
$$ = spice_append_str_values ($$, strdup ("V"), HINT_NAME | HINT_MSTART);
$$ = spice_append_str_values ($$, $1, HINT_NODE | HINT_MSTOP);
}
| VoltFunc Node { // TODO: 2 reduce/reduce
| VoltFunc Node %prec _NODE_ {
/* print/plot specification of node voltage */
$$ = NULL;
$$ = spice_append_str_values ($$, $1, HINT_NAME | HINT_MSTART);
Expand Down Expand Up @@ -843,7 +856,7 @@ DEVICE_List_3: /* nothing */ { $$ = NULL; }
$$ = netlist_append_values ($$, $2);
}
| IC_Condition_3 DEVICE_List_3 {
$$ = netlist_append_values ($1, $2);
$$ = netlist_append_values ($1, $2);
}
;

Expand Down Expand Up @@ -969,6 +982,6 @@ SubBodyLine:
%%

int spice_error (const char * error) {
fprintf (stderr, "line %d: %s\n", spice_lineno, error);
fprintf (stderr, "line %d: %s at id %d, token '%s'\n", spice_lineno, error, spice_char, spice_text);
return 0;
}
77 changes: 68 additions & 9 deletions src/converter/scan_spice.lpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
#include "check_spice.h"
#include "parse_spice.hpp"


/* fixing invalid identifiers */
static void spice_fix_identifier (char * ident) {
char * p;
Expand All @@ -62,9 +61,25 @@ static void spice_fix_identifier (char * ident) {
}
}

static void yy_push_state(int);
static void yy_pop_state();
static int yy_top_state();

void push_state(int state) {
yy_push_state(state);
}

void pop_state() {
yy_pop_state();
}

int top_state() {
return yy_top_state();
}

%}

WS [ \t\n\r]
WS [ \t]
TITLE [* \t0-9A-Za-z][A-Za-z0-9\- \t;#:=()/\.,*\\]*\r*\n
SPACE [ \t]
NAME [A-Z][A-Z0-9]*
Expand Down Expand Up @@ -134,8 +149,8 @@ POLY [pP][oO][lL][yY]

%x COMMENT IVREF DEVPROP LREF MODREF1 MODREF2 IGNORE FUNREF FILEREF VREF
%x STARTUP VSINGLE ISWITCH VSWITCH CONTROL GEVALS INLINE SUBCKT TLPROP RLCPROP
%x FHVALS
%option yylineno noyywrap nounput noinput prefix="spice_"
%x FHVALS DOUBLEVALUE LANODE
%option yylineno stack noyywrap nounput noinput prefix="spice_" header-file="scan_spice.hpp"
%%

<INITIAL>^{TITLE} { /* detect initial title lines */
Expand Down Expand Up @@ -499,6 +514,7 @@ POLY [pP][oO][lL][yY]
<STARTUP>^[qQ]{CSFX} { /* BJT instances */
spice_lval.ident = strdup (spice_text);
BEGIN(DEVPROP);
push_state(LANODE);
return Bipolar_Device;
}

Expand All @@ -524,17 +540,51 @@ POLY [pP][oO][lL][yY]
return End;
}

<DOUBLEVALUE>{NUMBER}|{DIGIT}+/{WS}({DIGIT}+|NUMBER) {
/* identify value followed by value */
spice_lval.ident = strdup (spice_text);
pop_state();
return Lookahead_Double_Value;
}

<LANODE>{NODE}|{IDENT}|{DIGIT}+/{WS}+({DIGIT}+|{NODE}|{IDENT}){WS}+({DIGIT}+|{NODE}|{IDENT}){WS}+({MODEL}|{IDENT}) {
/* identify node followed by 2 node */
spice_lval.ident = strdup (spice_text);
pop_state();
return Lookahead_Three_Node;
}

<LANODE>{NODE}|{IDENT}|{DIGIT}+/{WS}+({DIGIT}+|{NODE}|{IDENT}){WS}+({DIGIT}+|{NODE}|{IDENT}){WS}+({DIGIT}+|{NODE}|{IDENT}){WS}+({MODEL}|{IDENT}) {
/* identify node followed by 3 node */
spice_lval.ident = strdup (spice_text);
pop_state();
return Lookahead_Four_Node;
}

<LANODE>{NODE}|{IDENT}|{DIGIT}+/{WS}+({DIGIT}+|{NODE}|{IDENT}){WS}+({DIGIT}+|{NODE}|{IDENT}){WS}+({DIGIT}+|{NODE}|{IDENT}){WS}+({DIGIT}+|{NODE}|{IDENT}){WS}+({MODEL}|{IDENT}) {
/* identify node followed by 4 node */
spice_lval.ident = strdup (spice_text);
pop_state();
return Lookahead_Five_Node;
}

<STARTUP,IVREF,DEVPROP,LREF,FUNREF,VREF,VSINGLE,ISWITCH,VSWITCH,
GEVALS,TLPROP,RLCPROP,FHVALS>{DIGIT}+ {
GEVALS,TLPROP,RLCPROP,FHVALS,DOUBLEVALUE>{DIGIT}+ {
/* identify node (containing digits) */
spice_lval.ident = strdup (spice_text);
if (yy_start_stack_ptr > 0 && top_state() == DOUBLEVALUE) {
pop_state();
}
return Digits;
}

<STARTUP,IVREF,DEVPROP,LREF,FUNREF,VREF,VSINGLE,GEVALS,TLPROP,
RLCPROP,FHVALS>{NUMBER} {
RLCPROP,FHVALS,DOUBLEVALUE>{NUMBER} {
/* identify float (any kind) */
spice_lval.ident = strdup (spice_text);
if (yy_start_stack_ptr > 0 && top_state() == DOUBLEVALUE) {
pop_state();
}
return Floats;
}

Expand Down Expand Up @@ -563,9 +613,12 @@ POLY [pP][oO][lL][yY]
}

<STARTUP,DEVPROP,MODREF2,ISWITCH,VSWITCH,
TLPROP,RLCPROP>{IDENT} { /* arbitrary identifier */
TLPROP,RLCPROP,DOUBLEVALUE>{IDENT} { /* arbitrary identifier */
spice_lval.ident = strdup (spice_text);
spice_fix_identifier (spice_lval.ident);
if (yy_start_stack_ptr > 0 && top_state() == DOUBLEVALUE) {
pop_state();
}
return Identifier;
}

Expand Down Expand Up @@ -596,15 +649,21 @@ POLY [pP][oO][lL][yY]
}

<STARTUP,IVREF,DEVPROP,FUNREF,VREF,VSINGLE,ISWITCH,VSWITCH,GEVALS,
TLPROP,RLCPROP,FHVALS>{NODE} {
TLPROP,RLCPROP,FHVALS,DOUBLEVALUE>{NODE} {
/* identify node */
spice_lval.ident = strdup (spice_text);
if (yy_start_stack_ptr > 0 && top_state() == DOUBLEVALUE) {
pop_state();
}
return Nodes;
}

<STARTUP,IVREF,DEVPROP,LREF,IGNORE,FUNREF,FILEREF,VREF,VSINGLE,
ISWITCH,VSWITCH,GEVALS,SUBCKT,TLPROP,RLCPROP,FHVALS>{EOL} {
ISWITCH,VSWITCH,GEVALS,SUBCKT,TLPROP,RLCPROP,FHVALS,DOUBLEVALUE>{EOL} {
/* detect end of line */
if (yy_start_stack_ptr > 0 && top_state() == DOUBLEVALUE) {
pop_state();
}
BEGIN(STARTUP);
return Eol;
}
Expand Down
29 changes: 29 additions & 0 deletions tests/basic/components/spfile/bjt.cir
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.title dual rc ladder
* file name rcrcac.cir
*R1 int in 10k
*V1 in 0 dc 0 ac 1 PULSE (0 5 1u 1u 1u 1 1)
*R2 out int 1k
*C1 int 0 1u
*C2 out 0 100n

Q1 A B C BJTNAME
Q2 20 21 22 NPN 1.0
Q3 A B C BJTNAME 7.0 8.0
Q4 1 2 3 BJTNAME
Q5 20 20 97 PNP
Q6 21 21 22 A B NPN 1.0
Q7 A B C D BJTNAME

.MODEL PNP PNP(BF=200 CJC=20pf CJE=20pf IS=1E-16)
.MODEL NPN NPN(BF=200 CJC=20pf CJE=20pf IS=1E-16)
.MODEL BJTNAME NPN(BF=200 CJC=20pf CJE=20pf IS=1E-16)

.plot dc 1 2 3 4 5 6 7 8

*.control
*ac dec 10 1 100k
*plot vdb(out)
*plot ph(out)
*.endc


0 comments on commit cdf2767

Please sign in to comment.