Если я создаю синтаксический анализатор в своем собственном методе, я пытаюсь просто выполнить определение синтаксического анализатора и вернуть его, а вызывающий абонент отвечает за применение синтаксического анализатора к входной строке. Это упрощает интерфейс вызова для метода parser()
и значительно упрощает тестирование в отдельности.
Я изменил ваш метод parse()
на parser()
и поместил его в фиктивный класс X
,но оставил содержимое почти дословно, просто изменив ваш последний оператор синтаксического анализа на:
return dbuPerMicron | diearea | components
Затем я использовал этот код для запуска синтаксического анализатора с произвольно длинной выборкой (вашей опубликованной выборкой, плюс 10 000 000 случайных символов, включая пробелыи новые строки):
parser = X().parser()
# accumulate results using scanString
results = []
for t, s, e in parser.scanString(sample):
results.append(t)
# BUG! (sorry)
# if len(t) == 3:
if len(results) == 3:
break
# use builtin sum() function to merge all the parsed results into one
results = sum(results)
# or here is the same code as the above loop using islice to do the
# range checking for us
from itertools import islice
results = sum(t for t, s, e in islice(parser.scanString(sample), 0, 3))
# what did we get?
print(results.dump())
Создание бита длиной 10 миллионов символов было самой трудоемкой задачей, но анализ был остановлен после анализа 3 соответствующих сегментов. Я записал явное зацикливание с использованием scanString
, но с помощью itertools.islice
вы можете свернуть его до одной строки.
Вывод из results.dump()
выглядит следующим образом (длинные строки списка обрезаны для краткости публикации):
[['UNITS DISTANCE MICRONS', '2000'], ['0', '0', ...
- DIEAREA: ['0', '0', '46850', '39200']
- components: ['248', ['U293', 'NOR2_X1', 'PLACED', '6080', ...
- numComps: '248'
- subcomponents: [['U293', 'NOR2_X1', 'PLACED', '6080', ...
[0]:
['U293', 'NOR2_X1', 'PLACED', '6080', '0', 'N']
- PLACEMENT: ['PLACED', '6080', '0', 'N']
- cell: 'NOR2_X1'
- compName: ['U293', 'NOR2_X1']
- comp_name: 'U293'
- orientation: 'N'
- placement_x: '6080'
- placement_y: '0'
[1]:
['U294', 'FA_X1', 'PLACED', '0', '0', 'N']
- PLACEMENT: ['PLACED', '0', '0', 'N']
- cell: 'FA_X1'
- compName: ['U294', 'FA_X1']
- comp_name: 'U294'
- orientation: 'N'
- placement_x: '0'
- placement_y: '0'
[2]:
['U295', 'NAND2_X1', 'PLACED', '4560', '5600', 'N']
- PLACEMENT: ['PLACED', '4560', '5600', 'N']
- cell: 'NAND2_X1'
- compName: ['U295', 'NAND2_X1']
- comp_name: 'U295'
- orientation: 'N'
- placement_x: '4560'
- placement_y: '5600'
[3]:
['U296', 'FA_X1', 'PLACED', '20520', '2800', 'N']
- PLACEMENT: ['PLACED', '20520', '2800', 'N']
- cell: 'FA_X1'
- compName: ['U296', 'FA_X1']
- comp_name: 'U296'
- orientation: 'N'
- placement_x: '20520'
- placement_y: '2800'
[4]:
['U297', 'NAND2_X1', 'PLACED', '26600', '2800', 'N']
- PLACEMENT: ['PLACED', '26600', '2800', 'N']
- cell: 'NAND2_X1'
- compName: ['U297', 'NAND2_X1']
- comp_name: 'U297'
- orientation: 'N'
- placement_x: '26600'
- placement_y: '2800'
[5]:
['U298', 'NAND2_X1', 'PLACED', '27740', '2800', 'N']
- PLACEMENT: ['PLACED', '27740', '2800', 'N']
- cell: 'NAND2_X1'
- compName: ['U298', 'NAND2_X1']
- comp_name: 'U298'
- orientation: 'N'
- placement_x: '27740'
- placement_y: '2800'
[6]:
['U299', 'NAND2_X1', 'PLACED', '22800', '8400', 'N']
- PLACEMENT: ['PLACED', '22800', '8400', 'N']
- cell: 'NAND2_X1'
- compName: ['U299', 'NAND2_X1']
- comp_name: 'U299'
- orientation: 'N'
- placement_x: '22800'
- placement_y: '8400'
[7]:
['U300', 'NOR2_X1', 'PLACED', '25460', '5600', 'N']
- PLACEMENT: ['PLACED', '25460', '5600', 'N']
- cell: 'NOR2_X1'
- compName: ['U300', 'NOR2_X1']
- comp_name: 'U300'
- orientation: 'N'
- placement_x: '25460'
- placement_y: '5600'
[8]:
['U301', 'HA_X1', 'PLACED', '33440', '5600', 'N']
- PLACEMENT: ['PLACED', '33440', '5600', 'N']
- cell: 'HA_X1'
- compName: ['U301', 'HA_X1']
- comp_name: 'U301'
- orientation: 'N'
- placement_x: '33440'
- placement_y: '5600'
[9]:
['U540', 'INV_X1', 'PLACED', '760', '28000', 'N']
- PLACEMENT: ['PLACED', '760', '28000', 'N']
- cell: 'INV_X1'
- compName: ['U540', 'INV_X1']
- comp_name: 'U540'
- orientation: 'N'
- placement_x: '760'
- placement_y: '28000'
- dbuPerMicron: ['UNITS DISTANCE MICRONS', '2000']
- UnitsPerMicron: '2000'
Для элементов, которые, как вы знаете, будут целыми или действительными, вы можете использовать выражения для integer
и real
(или просто number
, которые будут соответствовать всем числовым формам), определенным вpyparsing.pyparsing_common
;эти выражения будут использовать быстрый Regex для синтаксического анализа и преобразовывать результат в правильный тип Python во время синтаксического анализа, чтобы вам не пришлось выполнять это преобразование позже.