Skip to content

Commit 2c66863

Browse files
authored
Merge pull request #263 from nunobrum/262-regex-error-with-comments-in-netlist
262 regex error with comments in netlist
2 parents a31a2c2 + 3b71be3 commit 2c66863

File tree

5 files changed

+26
-15
lines changed

5 files changed

+26
-15
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# README <!-- omit in toc -->
22

3-
_current version: 1.4.7_
3+
_current version: 1.4.8 (alpha)_
44

55
*spicelib* is a toolchain of python utilities design to interact with spice simulators, as for example:
66

@@ -1124,9 +1124,10 @@ in [GitHub spicelib issues](https://github.com/nunobrum/spicelib/issues)
11241124

11251125
## History
11261126
* Version 1.4.8
1127+
* Fixing Issue #262 - Support for comments in netlists
11271128
* SpiceEditor: Allow writing of netlists directly to an io.StringIO buffer (Issue #258)
11281129
* Version 1.4.7
1129-
* Implementing a lazy loading approach in RawRead
1130+
* Implementing a lazy loading approach in RawRead
11301131
* Fixing Issue #256 - Correct add_component() in SpiceEditor
11311132
* Support for string parameters - Issue #154
11321133
* Version 1.4.6

examples/testfiles/all_elements_lt.net

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ Q2 NC_38 NC_39 NC_40 BC517 temp=60 ic=0.6, 5
8484
* Rxxx n1 n2 <value> [tc=tc1, tc2, ...] [temp=<value>] ...
8585
* Rxxx n+ n- <value> <mname> <l=length> <w=width> ...
8686
* Rxxx n+ n- R = 'expression' <tc1=value> <tc2=value> <noisy=0> ...
87-
R1 in out 10k
87+
R1 in out 10k ; withcomments
8888
R2 NC_41 NC_42 R=2k5R
8989
R3 NC_41 NC_42 'V(cc) < {Vt} ? {R1} : {R2}' temp=13
9090
R4 in out 10k tol=1% pwr=0.1
@@ -114,7 +114,7 @@ W1 NC_56 NC_57 V1 W on
114114

115115
* Xxxx n1 n2 n3... <subckt name> [<parameter>=<expression>]
116116
XU1 1 2 a
117-
X§U2 NC_58 NC_59 NC_60 NC_61 NC_62 AD549
117+
X§U2 NC_58 NC_59 NC_60 NC_61 NC_62 AD549 ;§ withcomments
118118
XU3 NC_01 NC_02 NC_03 NC_04 NC_05 level2 Avol=1Meg GBW=10Meg Slew=10Meg Ilimit=25m Rail=0 Vos=0 En=0 Enk=0 In=0 Ink=0 Rin=500Meg
119119
XU4 in out1 V1 V2 out1 OPAx189 bla_v2 =1% bla_sp1=2 bla_sp2 = 3
120120
XU5 in out1 V1 V2 out1 GND OPAx189_float

spicelib/editor/spice_editor.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,15 @@ def PREFIX_AND_NODES_RGX(prefix: str, nodes_min: int, nodes_max: int = None) ->
7474
return "^(?P<designator>" + prefix + "§?\\w+)(?P<nodes>(?:\\s+[\\w+-\\.¥]+){" + nodes_str + "})"
7575

7676

77+
# Optional comment at end of line. Will consume trailing spaces and is to be used on all lines.
78+
COMMENT_RGX = r"(?:\s+;.*)?\\?\s*$"
79+
7780
# Potential model name, probably needs expanding. Will require a leading space
7881
MODEL_OR_VALUE_RGX = r"\s+(?P<value>[\w\.\-\{\}]+)"
7982

80-
# the rest of the line. Cannot be used with PARAM. Will require a leading space, and finish the line
81-
ANY_VALUE_RGX = r"\s+(?P<value>.*)$"
83+
# the rest of the line. Cannot be used with PARAM.
84+
# Includes the comment regex and will expect to finish the line.
85+
ANY_VALUE_RGX = r"\s+(?P<value>.*)" + COMMENT_RGX
8286

8387
# maybe a value. Will require a leading space
8488
MAYBE_VALUE_RGX = r"\s+(?P<value>.*?)"
@@ -108,8 +112,9 @@ def VALUE_RGX(prefix: str, number_regex_suffix: str) -> str:
108112

109113
# Parameters expression of the type: key = value.
110114
# key must be a full word without signs or dots
111-
# Value may be composite, and contain multiple spaces and quotes. Will expect to finish the line.
112-
PARAM_RGX = r"(?P<params>(\s+\w+\s*(=\s*[\w\{\}\(\)\-\+\*\/%\.\,'\"\s]+)?)*)?\\?\s*$"
115+
# Value may be composite, and contain multiple spaces and quotes.
116+
# Includes the comment regex and will expect to finish the line.
117+
PARAM_RGX = r"(?P<params>(\s+\w+\s*(=\s*[\w\{\}\(\)\-\+\*\/%\.\,'\"\s]+)?)*)?" + COMMENT_RGX
113118

114119

115120
REPLACE_REGEXS = {
@@ -153,11 +158,11 @@ def VALUE_RGX(prefix: str, number_regex_suffix: str) -> str:
153158
# Ixxx n+ n- R=<value>
154159
# Ixxx n+ n- PWL(t1 i1 t2 i2 t3 i3...)
155160
# Ixxx n+ n- wavefile=<filename> [chan=<nnn>]
156-
'I': PREFIX_AND_NODES_RGX("I", 2) + MAYBE_VALUE_RGX + r"(?P<params>(\s+\w+\s*=\s*[\w\{\}\(\)\-\+\*\/%\.\,'\"\s]+)*)$", # Independent Current Source
161+
'I': PREFIX_AND_NODES_RGX("I", 2) + MAYBE_VALUE_RGX + r"(?P<params>(\s+\w+\s*=\s*[\w\{\}\(\)\-\+\*\/%\.\,'\"\s]+)*)" + COMMENT_RGX, # Independent Current Source
157162
# Jxxx D G S <model> [area] [off] [IC=Vds, Vgs] [temp=T]
158163
'J': PREFIX_AND_NODES_RGX("J", 3) + MODEL_OR_VALUE_RGX + PARAM_RGX, # JFET
159164
# Kxxx Lyyy Lzzz ... value
160-
'K': PREFIX_AND_NODES_RGX("K", 2, 99) + r"\s+(?P<value>[\+\-]?[0-9\.E+-]+[kmuµnpgt]?).*$", # Mutual Inductance
165+
'K': PREFIX_AND_NODES_RGX("K", 2, 99) + r"\s+(?P<value>[\+\-]?[0-9\.E+-]+[kmuµnpgt]?)" + COMMENT_RGX, # Mutual Inductance
161166
# Lxxx n+ n- <value> <mname> <nt=val> <m=val> ...
162167
# Lxxx n+ n- L = 'expression' <tc1=value> <tc2=value>
163168
'L': PREFIX_AND_NODES_RGX("L", 2) + VALUE_RGX("L", r"(Meg|[kmuµnpgt])?H?\d*") + PARAM_RGX, # Inductance
@@ -192,14 +197,14 @@ def VALUE_RGX(prefix: str, number_regex_suffix: str) -> str:
192197
# Vxxx n+ n- PWL(t1 v1 t2 v2 t3 v3...)
193198
# Vxxx n+ n- wavefile=<filename> [chan=<nnn>]
194199
# ex: V1 NC_08 NC_09 PWL(1u 0 +2n 1 +1m 1 +2n 0 +1m 0 +2n -1 +1m -1 +2n 0) AC 1 2 Rser=3 Cpar=4
195-
'V': PREFIX_AND_NODES_RGX("V", 2) + MAYBE_VALUE_RGX + r"(?P<params>(\s+\w+\s*=\s*[\w\{\}\(\)\-\+\*\/%\.\,'\"\s]+)*)$", # Independent Voltage Source
200+
'V': PREFIX_AND_NODES_RGX("V", 2) + MAYBE_VALUE_RGX + r"(?P<params>(\s+\w+\s*=\s*[\w\{\}\(\)\-\+\*\/%\.\,'\"\s]+)*)" + COMMENT_RGX, # Independent Voltage Source
196201
# Wxxx n1 n2 Vnam <model> [on,off]
197202
'W': PREFIX_AND_NODES_RGX("W", 3) + ANY_VALUE_RGX, # Current Controlled Switch
198203
# Xxxx n1 n2 n3... <subckt name> [<parameter>=<expression>]
199204
# ex: XU1 NC_01 NC_02 NC_03 NC_04 NC_05 level2 Avol=1Meg GBW=10Meg Slew=10Meg Ilimit=25m Rail=0 Vos=0 En=0 Enk=0 In=0 Ink=0 Rin=500Meg
200205
# XU1 in out1 -V +V out1 OPAx189 bla_v2 =1% bla_sp1=2 bla_sp2 = 3
201206
# XU1 in out1 -V +V out1 GND OPAx189_float
202-
'X': PREFIX_AND_NODES_RGX("X", 1, 99) + MODEL_OR_VALUE_RGX + r"(?:\s+(?P<params>(?:\w+\s*=\s*['\"{]?.*?['\"}]?\s*)+))?\\?\s*$",
207+
'X': PREFIX_AND_NODES_RGX("X", 1, 99) + MODEL_OR_VALUE_RGX + r"(?:\s+(?P<params>(?:\w+\s*=\s*['\"{]?.*?['\"}]?\s*)+))?" + COMMENT_RGX, # Subcircuit Instance
203208
# (ngspice) Yxxx N1 0 N2 0 mname <LEN=LENGTH>
204209
# (qspice) Ynnn N+ N- <frequency1> dF=<value> Ctot=<value> [Q=<value>]
205210
'Y': PREFIX_AND_NODES_RGX("Y", 2, 4) + MODEL_OR_VALUE_RGX + PARAM_RGX, # Single Lossy Transmission Line

unittests/golden/all_elements_lt.net

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ Q2 NC_38 NC_39 NC_40 1e-9 temp=60 ic=0.6, 5
8282
* Rxxx n1 n2 <value> [tc=tc1, tc2, ...] [temp=<value>] ...
8383
* Rxxx n+ n- <value> <mname> <l=length> <w=width> ...
8484
* Rxxx n+ n- R = 'expression' <tc1=value> <tc2=value> <noisy=0> ...
85-
R1 in out 1e-9
85+
R1 in out 1e-9 ; withcomments
8686
R2 NC_41 NC_42 R= 1e-9
8787
R3 NC_41 NC_42 1e-9 temp=13
8888
R4 in out 1e-9 tol=1% pwr=0.1
@@ -112,7 +112,7 @@ W1 NC_56 NC_57 V1 1e-9
112112

113113
* Xxxx n1 n2 n3... <subckt name> [<parameter>=<expression>]
114114
XU1 1 2 1e-9
115-
XU2 NC_58 NC_59 NC_60 NC_61 NC_62 1e-9
115+
XU2 NC_58 NC_59 NC_60 NC_61 NC_62 1e-9 ;§ withcomments
116116
XU3 NC_01 NC_02 NC_03 NC_04 NC_05 1e-9 Avol=1Meg GBW=10Meg Slew=10Meg Ilimit=25m Rail=0 Vos=0 En=1e-09 In=0 Ink=0 Rin=500Meg blabla=1 2 3 4 5 6 7
117117
XU4 in out1 V1 V2 out1 1e-9 bla_v2=1e-09 bla_sp2=3 blabla=1 2 3 4 5 6 7
118118
XU5 in out1 V1 V2 out1 GND 1e-9

unittests/test_spice_editor.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,12 @@ def test_elements(self):
527527
for el, exp in expected.items():
528528
# print(f"Reading {el}")
529529
value = exp[0]
530-
self.assertEqual(edt.get_component_value(el).casefold(), value.casefold(), f"Test reading {el} Value")
530+
if value is None:
531+
value = ""
532+
v2 = edt.get_component_value(el)
533+
if v2 is None:
534+
v2 = ""
535+
self.assertEqual(v2.casefold(), value.casefold(), f"Test reading {el} Value")
531536
params = edt.get_component_parameters(el)
532537
self.assertDictEqual(params, params | exp[1], f"Test reading {el} Parameters")
533538

0 commit comments

Comments
 (0)