You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.4 KiB
Python
103 lines
2.4 KiB
Python
2 years ago
|
#!/usr/bin/python3
|
||
|
"""
|
||
|
Ini file sample (see end of file for the content of the ini file)
|
||
|
|
||
|
To parse an ini file we use the grammar below. Comments in ini files are
|
||
|
starting with a semicolon ";".
|
||
|
|
||
|
>>> ini_file = parse(ini_file_text, IniFile, comment=(";", restline))
|
||
|
|
||
|
Because IniFile and Section are Namespaces, we can access their content by
|
||
|
name.
|
||
|
|
||
|
>>> print("found: " + repr(ini_file["Number 1"]["that"]))
|
||
|
found: ...'something else'
|
||
|
|
||
|
pyPEG is measuring the position of each object in the input text with a
|
||
|
tuple (line_number, offset).
|
||
|
|
||
|
>>> ini_file["Number 1"]["that"].position_in_text
|
||
|
(3, 26)
|
||
|
>>> ini_file["Number 2"].position_in_text
|
||
|
(6, 85)
|
||
|
|
||
|
pyPEG can also do the reverse job, composing a text of an object tree.
|
||
|
|
||
|
>>> ini_file["Number 1"]["that"] = Key("new one")
|
||
|
>>> ini_file["Number 3"] = Section()
|
||
|
>>> print(compose(ini_file))
|
||
|
[Number 1]
|
||
|
this=something
|
||
|
that=new one
|
||
|
[Number 2]
|
||
|
once=anything
|
||
|
twice=goes
|
||
|
[Number 3]
|
||
|
...
|
||
|
|
||
|
pyPEG contains an XML backend, too:
|
||
|
|
||
|
>>> from pypeg2.xmlast import thing2xml
|
||
|
>>> print(thing2xml(ini_file, pretty=True).decode())
|
||
|
<IniFile>
|
||
|
<Section name="Number 1">
|
||
|
<Key name="this">something</Key>
|
||
|
<Key name="that">new one</Key>
|
||
|
</Section>
|
||
|
<Section name="Number 2">
|
||
|
<Key name="once">anything</Key>
|
||
|
<Key name="twice">goes</Key>
|
||
|
</Section>
|
||
|
<Section name="Number 3"/>
|
||
|
</IniFile>
|
||
|
...
|
||
|
|
||
|
In this sample the tree contains named objects only. Then we can output object
|
||
|
names as tag names. Spaces in names will be translated into underscores.
|
||
|
|
||
|
>>> print(thing2xml(ini_file, pretty=True, object_names=True).decode())
|
||
|
<IniFile>
|
||
|
<Number_1>
|
||
|
<this>something</this>
|
||
|
<that>new one</that>
|
||
|
</Number_1>
|
||
|
<Number_2>
|
||
|
<once>anything</once>
|
||
|
<twice>goes</twice>
|
||
|
</Number_2>
|
||
|
<Number_3/>
|
||
|
</IniFile>
|
||
|
...
|
||
|
"""
|
||
|
|
||
|
from __future__ import unicode_literals, print_function
|
||
|
from pypeg2 import *
|
||
|
import re
|
||
|
|
||
|
# ini file parser
|
||
|
|
||
|
# symbols in ini files can include spaces
|
||
|
Symbol.regex = re.compile(r"[\w\s]+")
|
||
|
|
||
|
class Key(str):
|
||
|
grammar = name(), "=", restline, endl
|
||
|
|
||
|
class Section(Namespace):
|
||
|
grammar = "[", name(), "]", endl, maybe_some(Key)
|
||
|
|
||
|
class IniFile(Namespace):
|
||
|
grammar = some(Section)
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
ini_file_text = """[Number 1]
|
||
|
this=something
|
||
|
that=something else
|
||
|
|
||
|
; now for something even more useless
|
||
|
[Number 2]
|
||
|
once=anything
|
||
|
twice=goes
|
||
|
"""
|
||
|
import doctest
|
||
|
doctest.testmod(optionflags=(doctest.ELLIPSIS | doctest.REPORT_ONLY_FIRST_FAILURE))
|