gpt4 book ai didi

python - PyParsing Optional() 挂起

转载 作者:行者123 更新时间:2023-12-03 13:29:33 28 4
gpt4 key购买 nike

仅使用 Optional 或 ZeroOrMore 时,pyparsing 似乎进入了无限循环。以下代码有效,但“# 应该与 pp.Optional() 一起使用”部分确实应该是 Optional 而不是 OneOrMore。在这种情况下,我应该放置某种 stopOn 吗?

字典如下图所示:

其中 [expr] 表示可选 expr,而 [expr]... 表示可以重复的可选 expr,所以 ZeroOrMore:

[PINS numPins ;
[ – pinName + NET netName
[+ SPECIAL]
[+ DIRECTION {INPUT | OUTPUT | INOUT | FEEDTHRU}]
[+ NETEXPR "netExprPropName defaultNetName"]
[+ SUPPLYSENSITIVITY powerPinName]
[+ GROUNDSENSITIVITY groundPinName]
[+ USE {SIGNAL | POWER | GROUND | CLOCK | TIEOFF | ANALOG | SCAN | RESET}]
[+ ANTENNAPINPARTIALMETALAREA value [LAYER layerName]] ...
[+ ANTENNAPINPARTIALMETALSIDEAREA value [LAYER layerName]] ...
[+ ANTENNAPINPARTIALCUTAREA value [LAYER layerName]] ...
[+ ANTENNAPINDIFFAREA value [LAYER layerName]] ...
[+ ANTENNAMODEL {OXIDE1 | OXIDE2 | OXIDE3 | OXIDE4}] ...
[+ ANTENNAPINGATEAREA value [LAYER layerName]] ...
[+ ANTENNAPINMAXAREACAR value LAYER layerName] ...
[+ ANTENNAPINMAXSIDEAREACAR value LAYER layerName] ...
[+ ANTENNAPINMAXCUTCAR value LAYER layerName] ...
[ # The code shows only this section
[+ PORT]
[+ LAYER layerName
[MASK maskNum]
[SPACING minSpacing | DESIGNRULEWIDTH effectiveWidth] pt pt
|+ POLYGON layerName
[MASK maskNum]
[SPACING minSpacing | DESIGNRULEWIDTH effectiveWidth] pt pt pt ...
|+ VIA viaName
[MASK viaMaskNum] pt
] ...
[+ COVER pt orient | FIXED pt orient | PLACED pt orient] # This must be Optional
]...
; ] ...
END PINS]

这是解析器(它只显示 PLACEMENT_PINS 部分)。
# PLACEMENT_PINS
PORT = (ws_pin
+ pp.Keyword('PORT')('PORT')
)

MASK = pp.Group(pp.Keyword('MASK')
+ number('maskNum')
).setResultsName('MASK')

SPACING = pp.Group(pp.Keyword('SPACING')
+ number('minSpacing')
).setResultsName('SPACING')

DESIGNRULEWIDTH = pp.Group(pp.Keyword('DESIGNRULEWIDTH')
+ number('effectiveWidth')
).setResultsName('DESIGNRULEWIDTH')

LAYER = pp.Group(ws_pin
+ pp.Suppress(pp.Keyword('LAYER')) + identifier('layerName')
+ pp.Optional(MASK)
+ pp.Optional(SPACING | DESIGNRULEWIDTH)
+ pp.OneOrMore(pp.Group(pt))('coord')
).setResultsName('LAYER')

POLYGON = pp.Group(ws_pin
+ pp.Suppress(pp.Keyword('POLYGON')) + identifier('layerName')
+ pp.Optional(MASK)
+ pp.Optional(SPACING | DESIGNRULEWIDTH)
+ pp.OneOrMore(pp.Group(pt))('coord')
).setResultsName('POLYGON')

VIA = pp.Group(ws_pin
+ pp.Suppress(pp.Keyword('VIA')) + identifier('viaName')
+ pp.Optional(MASK)
+ pp.Group(pt)('coord')
).setResultsName('VIA')

COVER = pp.Group(ws_pin
+ pp.Keyword('COVER')
+ pp.Group(pt)('coord')
+ ORIENT('orient')
).setResultsName('COVER')
FIXED = pp.Group(ws_pin
+ pp.Keyword('FIXED')
+ pp.Group(pt)('coord')
+ ORIENT('orient')
).setResultsName('FIXED')
PLACED = pp.Group(ws_pin
+ pp.Keyword('PLACED')
+ pp.Group(pt)('coord')
+ ORIENT('orient')
).setResultsName('PLACED')

PLACEMENT_PINS = pp.Group(pp.Optional(PORT)
+ pp.ZeroOrMore(LAYER | POLYGON | VIA)
+ pp.OneOrMore(COVER | FIXED | PLACED) # Should work with pp.Optional(), but it doesn't.
)

pin = pp.Group(pp.Suppress(begin_pin)
+ pinName
+ pp.Optional(SPECIAL)
+ pp.Optional(DIRECTION)
+ pp.Optional(NETEXPR)
+ pp.Optional(SUPPLYSENSITIVITY)
+ pp.Optional(GROUNDSENSITIVITY)
+ pp.Optional(USE)
+ pp.ZeroOrMore(ANTENNAPINPARTIALMETALAREA)
+ pp.ZeroOrMore(ANTENNAPINPARTIALMETALSIDEAREA)
+ pp.ZeroOrMore(ANTENNAPINPARTIALCUTAREA)
+ pp.ZeroOrMore(ANTENNAPINDIFFAREA)
+ pp.ZeroOrMore(ANTENNAMODEL)
+ pp.ZeroOrMore(ANTENNAPINGATEAREA)
+ pp.ZeroOrMore(ANTENNAPINMAXAREACAR)
+ pp.ZeroOrMore(ANTENNAPINMAXSIDEAREACAR)
+ pp.ZeroOrMore(ANTENNAPINMAXCUTCAR)
+ pp.ZeroOrMore(PLACEMENT_PINS).setResultsName('PLACEMENT')
+ pp.Suppress(linebreak)
).setResultsName('pin', listAllMatches=True)

pins = pp.Group(pp.Suppress(pins_id) + number('numPins') + pp.Suppress(linebreak)
+ pp.ZeroOrMore(pin)
+ pp.Suppress(end_pins_id)
).setResultsName('PINS')

这是要解析的文本的示例:
PINS 165 ;
- clk + NET clk + DIRECTION INPUT + USE SIGNAL
+ LAYER M2 ( -25 0 ) ( 25 220 )
+ PLACED ( 0 81500 ) E ;
- rst + NET rst + DIRECTION INPUT + USE SIGNAL
+ LAYER M5 ( -25 0 ) ( 25 220 )
+ PLACED ( 96300 140000 ) S ;
- im_rsc_CSN + NET im_rsc_CSN + DIRECTION OUTPUT + USE SIGNAL
+ LAYER M3 ( -25 0 ) ( 25 220 )
+ PLACED ( 80300 140000 ) S ;
END PINS

在此示例中,如果删除了“+ PLACED”行,解析器将不起作用,因为它是“pp.OneOrMore(COVER | FIXED | PLACED)”而不是“pp.Optional(COVER | FIXED | PLACED)”。

要解析的其他部分是 UNITS。 所有表达式都是可选的,即文件可以包含“TIME NANOSECONDS 1000”等。
[UNITS
[TIME NANOSECONDS convertFactor ;]
[CAPACITANCE PICOFARADS convertFactor ;]
[RESISTANCE OHMS convertFactor ;]
[POWER MILLIWATTS convertFactor ;]
[CURRENT MILLIAMPS convertFactor ;]
[VOLTAGE VOLTS convertFactor ;]
[DATABASE MICRONS LEFconvertFactor ;]
[FREQUENCY MEGAHERTZ convertFactor ;]
END UNITS]

这是挂起的解析器,因为所有表达式都是可选的:
# DATABASE_MICRONS
DATABASE_MICRONS = (pp.Keyword('DATABASE MICRONS')
+ number('convertFactor')
+ linebreak
)
unit = pp.Group(pp.Optional(TIME_NANOSECONDS)
+ pp.Optional(CAPACITANCE_PICOFARADS)
+ pp.Optional(RESISTANCE_OHMS)
+ pp.Optional(POWER_MILLIWATTS)
+ pp.Optional(CURRENT_MILLIAMPS)
+ pp.Optional(VOLTAGE_VOLTS)
+ pp.Optional(DATABASE_MICRONS)
+ pp.Optional(FREQUENCY_MEGAHERTZ)
).setResultsName('unit', listAllMatches=True)

units = pp.Group(pp.Suppress(units_id)
+ pp.OneOrMore(unit)
+ pp.Suppress(end_units_id)
).setResultsName('UNITS')

但是,如果我用“+ pp.OneOrMore(DATABASE_MICRONS)”替换其中一行,例如“+ pp.Optional(DATABASE_MICRONS)”(那么文件现在必须包含此表达式),那么它将起作用。

UNITS 部分的示例:
UNITS
DATABASE MICRONS 1000 ;
END UNITS

那么,如何处理所有表达式都是可选的语法呢?

最佳答案

如果PLACEMENT_PINS中的所有元素是可选的,那么它将匹配空字符串。匹配ZeroOrMore匹配空字符串的表达式将永远循环。

是否所有的 ZeroOrMore 都在那里,因为你不知道顺序是什么?如果是这样,请考虑使用“&”运算符而不是“+”。 a_expr & b_expr & c_expr将匹配三个表达式,但以任何顺序。

编辑:
我知道它们都是可选的,但是因为您将它们集中到了它们自己的 unit 中。表达一切Optional (因此可以与空字符串匹配)
然后是 OneOrMore对他们来说,这是另一个无限循环。

当你说“它们都是可选的”时,我理解从定义UNITS的角度来看它们都是可选的。部分。但是OneOrMoreunits已经
照顾重复。如果为空 UNITS部分有效,然后使用 ZeroOrMore .

这些对我来说看起来像是“单位短语”,每个词都是单位上的一些多词限定词,其中任何一个或全部可能存在,数量不限。

不是将它们全部添加为 Optionals,而是将它们定义为单个 MatchFirst -“一个单元短语是特定短语之一”。
OneOrMore将处理重复和可选:

unit_phrase = pp.Group(TIME_NANOSECONDS
| CAPACITANCE_PICOFARADS
| RESISTANCE_OHMS
| POWER_MILLIWATTS
| CURRENT_MILLIAMPS
| VOLTAGE_VOLTS
| DATABASE_MICRONS
| FREQUENCY_MEGAHERTZ)

units = pp.Group(pp.Suppress(units_id)
+ pp.OneOrMore(unit_phrase)('unit')
+ pp.Suppress(end_units_id)
).setResultsName('UNITS')

如果事实上这些都可以是可选的但必须只出现一次,那么定义一个 EachOptional s 是你想要的,没有重复:
unit = pp.Group(pp.Optional(TIME_NANOSECONDS)
& pp.Optional(CAPACITANCE_PICOFARADS)
& pp.Optional(RESISTANCE_OHMS)
& pp.Optional(POWER_MILLIWATTS)
& pp.Optional(CURRENT_MILLIAMPS)
& pp.Optional(VOLTAGE_VOLTS)
& pp.Optional(DATABASE_MICRONS)
& pp.Optional(FREQUENCY_MEGAHERTZ)
)

units = pp.Group(pp.Suppress(units_id)
+ unit.setResultsName('unit') # <-- no OneOrMore repetition now, let Each do the orderless matching
+ pp.Suppress(end_units_id)
).setResultsName('UNITS')

关于python - PyParsing Optional() 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58734931/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com