Rewritten for parsing fields.
This commit is contained in:
parent
24b1fef890
commit
6a6c32b562
5
README
5
README
|
@ -1,4 +1,5 @@
|
||||||
A simple script for parsing TRM register definition...
|
A simple script for parsing TRM register definition...
|
||||||
|
|
||||||
Example Usage:
|
Experimenting
|
||||||
pdftotext -f 1431 -l 1434 -layout ug585-Zynq-7000-TRM.pdf - | python main.py 0x1000 0x1FFC
|
|
||||||
|
pdftotext -f 1436 -l 1438 -layout ug585-Zynq-7000-TRM.pdf - | python main.py
|
||||||
|
|
121
main.py
121
main.py
|
@ -1,54 +1,104 @@
|
||||||
from typing import Optional, Dict
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
def parse_table_entries(fields, pattern, lines):
|
def parse_table_entries(fields):
|
||||||
"""Parse aligned table entries"""
|
"""Parse aligned table entries"""
|
||||||
prev: Optional[Dict] = None
|
pattern = r'\s+'.join([f"(?P<{v[:v.find(':')]}>{v[v.find(':') + 1:].strip()})"
|
||||||
|
for v in fields])
|
||||||
|
pattern = re.compile(pattern)
|
||||||
|
fields = [v[:v.find(':')] for v in fields]
|
||||||
|
prev = None
|
||||||
entries = []
|
entries = []
|
||||||
def flush():
|
def flush():
|
||||||
nonlocal prev
|
nonlocal prev
|
||||||
if prev is not None:
|
if prev is not None:
|
||||||
entries.append(prev['data'])
|
entries.append(prev['data'])
|
||||||
prev = None
|
prev = None
|
||||||
for line in lines:
|
|
||||||
|
while True:
|
||||||
|
line = yield
|
||||||
|
if line == None:
|
||||||
|
break
|
||||||
if len(line.strip()) == 0:
|
if len(line.strip()) == 0:
|
||||||
flush()
|
flush()
|
||||||
continue
|
continue
|
||||||
|
match = pattern.fullmatch(line.strip())
|
||||||
match = pattern.search(line.strip())
|
|
||||||
if match is not None:
|
if match is not None:
|
||||||
flush()
|
flush()
|
||||||
starts = [match.span(v)[0] for v in fields] + [len(line)]
|
starts = [match.span(v)[0] for v in fields]
|
||||||
prev = {
|
prev = {
|
||||||
'data': {v: match.group(v) for v in fields},
|
'data': {v: [match.group(v)] for v in fields},
|
||||||
'starts': starts
|
'starts': starts
|
||||||
}
|
}
|
||||||
elif prev is not None:
|
elif prev is not None:
|
||||||
for i, field in enumerate(fields):
|
for i, field in enumerate(fields):
|
||||||
v = line[prev['starts'][i]:prev['starts'][i + 1]].strip()
|
if i + 1 == len(fields):
|
||||||
|
v = line[prev['starts'][i]:].strip()
|
||||||
|
else:
|
||||||
|
v = line[prev['starts'][i]:prev['starts'][i + 1]].strip()
|
||||||
if len(v) == 0:
|
if len(v) == 0:
|
||||||
continue
|
continue
|
||||||
if prev['data'][field][-1] not in ['-', '_']:
|
prev['data'][field].append(v)
|
||||||
v = ' ' + v
|
|
||||||
prev['data'][field] += v
|
|
||||||
|
|
||||||
flush()
|
flush()
|
||||||
return entries
|
return entries
|
||||||
|
|
||||||
|
# def parse_register_list(lines):
|
||||||
|
# """Parse register entry from `pdftotext -layout output` from TRM table"""
|
||||||
|
# fields = [
|
||||||
|
# r'id: \w+',
|
||||||
|
# r'address: 0x[0-9A-F]+',
|
||||||
|
# r'size: \d+',
|
||||||
|
# r'type: \w+',
|
||||||
|
# r'reset_value: 0x[0-9A-F]+',
|
||||||
|
# r'description: .+'
|
||||||
|
# ]
|
||||||
|
# return parse_table_entries(fields, lines)
|
||||||
|
|
||||||
def parse_registers(lines):
|
def parse_register_fields():
|
||||||
"""Parse register entry from `pdftotext -layout output` from TRM table"""
|
fields = [
|
||||||
fields = ['id', 'address', 'size', 'type', 'reset_value', 'description']
|
r'name: \w+',
|
||||||
|
r'bits: \d+(:\d+)?',
|
||||||
|
r'type: \w+',
|
||||||
|
r'reset: 0x[0-9A-F]+',
|
||||||
|
r'description: .+'
|
||||||
|
]
|
||||||
|
it = parse_table_entries(fields)
|
||||||
|
next(it)
|
||||||
|
return it
|
||||||
|
|
||||||
ENTRY_PATTERN = re.compile(r'^'
|
def end_iterator(it):
|
||||||
r'(?P<id>\w+)\s+'
|
try:
|
||||||
r'(?P<address>0x[0-9A-F]+)\s+'
|
it.send(None)
|
||||||
r'(?P<size>\d+)\s+'
|
except StopIteration as e:
|
||||||
r'(?P<type>\w+)\s+'
|
return e.value
|
||||||
r'(?P<reset_value>0x[0-9A-F]+)\s+'
|
|
||||||
r'(?P<description>.+)$')
|
def parse_registers():
|
||||||
return parse_table_entries(fields, ENTRY_PATTERN, lines)
|
def inner():
|
||||||
|
pattern = re.compile(r'Name\s+(\w+)')
|
||||||
|
state = 0
|
||||||
|
name = ''
|
||||||
|
it = None
|
||||||
|
results = {}
|
||||||
|
while True:
|
||||||
|
line = yield
|
||||||
|
if line == None:
|
||||||
|
break
|
||||||
|
line = line.strip()
|
||||||
|
m = pattern.fullmatch(line)
|
||||||
|
if m is not None:
|
||||||
|
if it is not None:
|
||||||
|
results[name] = end_iterator(it)
|
||||||
|
name = m.group(1)
|
||||||
|
it = parse_register_fields()
|
||||||
|
else:
|
||||||
|
if it is not None:
|
||||||
|
it.send(line)
|
||||||
|
if it is not None:
|
||||||
|
results[name] = end_iterator(it)
|
||||||
|
return results
|
||||||
|
it = inner()
|
||||||
|
next(it)
|
||||||
|
return it
|
||||||
|
|
||||||
def emit_rust(base_addr, ending_addr, registers):
|
def emit_rust(base_addr, ending_addr, registers):
|
||||||
current_addr = base_addr
|
current_addr = base_addr
|
||||||
|
@ -89,10 +139,21 @@ def emit_rust(base_addr, ending_addr, registers):
|
||||||
code.append(line)
|
code.append(line)
|
||||||
return code
|
return code
|
||||||
|
|
||||||
if len(sys.argv) != 3:
|
|
||||||
print("Pipe pdftotext to stdin, and give starting and ending address"
|
|
||||||
"(inclusive) for the registers")
|
|
||||||
exit()
|
|
||||||
|
|
||||||
for line in emit_rust(int(sys.argv[1], 0), int(sys.argv[2], 0), parse_registers(sys.stdin)):
|
|
||||||
print(line)
|
# if len(sys.argv) != 3:
|
||||||
|
# print("Pipe pdftotext to stdin, and give starting and ending address"
|
||||||
|
# "(inclusive) for the registers")
|
||||||
|
# exit()
|
||||||
|
|
||||||
|
# for line in emit_rust(int(sys.argv[1], 0), int(sys.argv[2], 0), parse_register_list(sys.stdin)):
|
||||||
|
# print(line)
|
||||||
|
|
||||||
|
parser = parse_registers()
|
||||||
|
for line in sys.stdin:
|
||||||
|
parser.send(line)
|
||||||
|
for k, v in end_iterator(parser).items():
|
||||||
|
print(k)
|
||||||
|
for entry in v:
|
||||||
|
print(entry)
|
||||||
|
print('------------')
|
||||||
|
|
Loading…
Reference in New Issue