仅使用Optional或ZeroOrMore时,pyparsing似乎进入了无限循环。以下代码可以工作,但是“#应该与pp.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
那么,如何处理所有表达式都是可选的语法呢?
python大神给出的解决方案
如果PLACEMENT_PINS
中的所有元素都是可选的,则它将匹配空字符串。与空字符串匹配的表达式的ZeroOrMore
匹配将永远循环。
因为您不知道订单是什么,所有的ZeroOrMore都在那里吗?如果是这样,请考虑使用“&”运算符而不是“ +”。 a_expr & b_expr & c_expr
将匹配这三个表达式,但顺序不限。
编辑:
我知道它们都是可选的,但是因为您已经将它们与所有unit
组合成自己的Optional
表达式(因此可以与空字符串匹配)
然后OneOrMore
对其进行处理,这是另一个无限循环。
当您说“它们都是可选的”时,我理解从定义UNITS
部分的角度来看,它们都是可选的。但是OneOrMore
中的units
已经
照顾重复。如果空的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')
如果实际上所有这些都是可选的,但只能出现一次,那么您想要的就是定义Each
的Optional
,而无需重复:
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 pytz时区函数返回的时区为9分钟 - python由于某些原因,我无法从以下代码中找出原因:>>> from pytz import timezone >>> timezone('America/Chicago') 我得到:<DstTzInfo 'America/Chicago' LMT-1 day, 18:09:00 STD…
Python:同时在for循环中添加到列表列表 - python我想用for循环外的0索引值创建一个新列表,然后使用for循环添加到相同的列表。我的玩具示例是:import random data = ['t1', 't2', 't3'] masterlist = [['col1', 'animal1', 'an…
用大写字母拆分字符串,但忽略AAA Python Regex - python我的正则表达式:vendor = "MyNameIsJoe. I'mWorkerInAAAinc." ven = re.split(r'(?<=[a-z])[A-Z]|[A-Z](?=[a-z])', vendor) 以大写字母分割字符串,例如:'我的名字是乔。 I'mWorkerInAAAinc”变成…
如何获取Python中所有内置函数的列表 - python当我们从中获取关键字列表时,如何从Python提示符中获取Python中所有内置函数的列表? python大神给出的解决方案 更新:关于__builtins__或__builtin__可能会有一些混淆。What’s New In Python 3.0建议使用builtins 将模块__builtin__重命名为builtins(删除下划线, 添加一个“ s”…
Python查找单词可以用字符构建 - pythonClosed. This question needs details or clarity。它当前不接受答案。 想改善这个问题吗?添加详细信息并通过editing this post阐明问题。 4个月前关闭。 Improve this question 我想找出单词'apple'(word_list)是否可以用char_list1构建但不能用char_li…