diff options
Diffstat (limited to 'examples/dfmparse.py')
-rw-r--r-- | examples/dfmparse.py | 122 |
1 files changed, 89 insertions, 33 deletions
diff --git a/examples/dfmparse.py b/examples/dfmparse.py index 5a1d2a0..5d9b1b1 100644 --- a/examples/dfmparse.py +++ b/examples/dfmparse.py @@ -8,21 +8,36 @@ __version__ = "1.0" __author__ = "Daniel 'Dang' Griffith <pythondev - dang at lazytwinacres . net>"
-from pyparsing import Literal, CaselessLiteral, Word, delimitedList \
- , Optional, Combine, Group, alphas, nums, alphanums, Forward \
- , oneOf, OneOrMore, ZeroOrMore, CharsNotIn
+from pyparsing import (
+ Literal,
+ CaselessLiteral,
+ Word,
+ delimitedList,
+ Optional,
+ Combine,
+ Group,
+ alphas,
+ nums,
+ alphanums,
+ Forward,
+ oneOf,
+ OneOrMore,
+ ZeroOrMore,
+ CharsNotIn,
+)
# This converts DFM character constants into Python string (unicode) values.
def to_chr(x):
"""chr(x) if 0 < x < 128 ; unicode(x) if x > 127."""
- return 0 < x < 128 and chr(x) or eval("u'\\u%d'" % x )
+ return 0 < x < 128 and chr(x) or eval("u'\\u%d'" % x)
+
#################
# BEGIN GRAMMAR
#################
-COLON = Literal(":").suppress()
+COLON = Literal(":").suppress()
CONCAT = Literal("+").suppress()
EQUALS = Literal("=").suppress()
LANGLE = Literal("<").suppress()
@@ -33,66 +48,100 @@ RANGLE = Literal(">").suppress() RBRACE = Literal("]").suppress()
RPAREN = Literal(")").suppress()
-CATEGORIES = CaselessLiteral("categories").suppress()
-END = CaselessLiteral("end").suppress()
-FONT = CaselessLiteral("font").suppress()
-HINT = CaselessLiteral("hint").suppress()
-ITEM = CaselessLiteral("item").suppress()
-OBJECT = CaselessLiteral("object").suppress()
+CATEGORIES = CaselessLiteral("categories").suppress()
+END = CaselessLiteral("end").suppress()
+FONT = CaselessLiteral("font").suppress()
+HINT = CaselessLiteral("hint").suppress()
+ITEM = CaselessLiteral("item").suppress()
+OBJECT = CaselessLiteral("object").suppress()
-attribute_value_pair = Forward() # this is recursed in item_list_entry
+attribute_value_pair = Forward() # this is recursed in item_list_entry
simple_identifier = Word(alphas, alphanums + "_")
-identifier = Combine( simple_identifier + ZeroOrMore( Literal(".") + simple_identifier ))
+identifier = Combine(simple_identifier + ZeroOrMore(Literal(".") + simple_identifier))
object_name = identifier
object_type = identifier
# Integer and floating point values are converted to Python longs and floats, respectively.
-int_value = Combine(Optional("-") + Word(nums)).setParseAction(lambda s,l,t: [ int(t[0]) ] )
-float_value = Combine(Optional("-") + Optional(Word(nums)) + "." + Word(nums)).setParseAction(lambda s,l,t: [ float(t[0]) ] )
+int_value = Combine(Optional("-") + Word(nums)).setParseAction(
+ lambda s, l, t: [int(t[0])]
+)
+float_value = Combine(
+ Optional("-") + Optional(Word(nums)) + "." + Word(nums)
+).setParseAction(lambda s, l, t: [float(t[0])])
number_value = float_value | int_value
# Base16 constants are left in string form, including the surrounding braces.
-base16_value = Combine(Literal("{") + OneOrMore(Word("0123456789ABCDEFabcdef")) + Literal("}"), adjacent=False)
+base16_value = Combine(
+ Literal("{") + OneOrMore(Word("0123456789ABCDEFabcdef")) + Literal("}"),
+ adjacent=False,
+)
# This is the first part of a hack to convert the various delphi partial sglQuotedStrings
# into a single sglQuotedString equivalent. The gist of it is to combine
# all sglQuotedStrings (with their surrounding quotes removed (suppressed))
# with sequences of #xyz character constants, with "strings" concatenated
# with a '+' sign.
-unquoted_sglQuotedString = Combine( Literal("'").suppress() + ZeroOrMore( CharsNotIn("'\n\r") ) + Literal("'").suppress() )
+unquoted_sglQuotedString = Combine(
+ Literal("'").suppress() + ZeroOrMore(CharsNotIn("'\n\r")) + Literal("'").suppress()
+)
# The parse action on this production converts repetitions of constants into a single string.
pound_char = Combine(
- OneOrMore((Literal("#").suppress()+Word(nums)
- ).setParseAction( lambda s, l, t: to_chr(int(t[0]) ))))
+ OneOrMore(
+ (Literal("#").suppress() + Word(nums)).setParseAction(
+ lambda s, l, t: to_chr(int(t[0]))
+ )
+ )
+)
# This is the second part of the hack. It combines the various "unquoted"
# partial strings into a single one. Then, the parse action puts
# a single matched pair of quotes around it.
delphi_string = Combine(
- OneOrMore(CONCAT | pound_char | unquoted_sglQuotedString)
- , adjacent=False
- ).setParseAction(lambda s, l, t: "'%s'" % t[0])
+ OneOrMore(CONCAT | pound_char | unquoted_sglQuotedString), adjacent=False
+).setParseAction(lambda s, l, t: "'%s'" % t[0])
string_value = delphi_string | base16_value
-list_value = LBRACE + Optional(Group(delimitedList(identifier | number_value | string_value))) + RBRACE
-paren_list_value = LPAREN + ZeroOrMore(identifier | number_value | string_value) + RPAREN
+list_value = (
+ LBRACE
+ + Optional(Group(delimitedList(identifier | number_value | string_value)))
+ + RBRACE
+)
+paren_list_value = (
+ LPAREN + ZeroOrMore(identifier | number_value | string_value) + RPAREN
+)
item_list_entry = ITEM + ZeroOrMore(attribute_value_pair) + END
item_list = LANGLE + ZeroOrMore(item_list_entry) + RANGLE
generic_value = identifier
-value = item_list | number_value | string_value | list_value | paren_list_value | generic_value
+value = (
+ item_list
+ | number_value
+ | string_value
+ | list_value
+ | paren_list_value
+ | generic_value
+)
category_attribute = CATEGORIES + PERIOD + oneOf("strings itemsvisibles visibles", True)
-event_attribute = oneOf("onactivate onclosequery onclose oncreate ondeactivate onhide onshow", True)
+event_attribute = oneOf(
+ "onactivate onclosequery onclose oncreate ondeactivate onhide onshow", True
+)
font_attribute = FONT + PERIOD + oneOf("charset color height name style", True)
hint_attribute = HINT
layout_attribute = oneOf("left top width height", True)
generic_attribute = identifier
-attribute = (category_attribute | event_attribute | font_attribute | hint_attribute | layout_attribute | generic_attribute)
+attribute = (
+ category_attribute
+ | event_attribute
+ | font_attribute
+ | hint_attribute
+ | layout_attribute
+ | generic_attribute
+)
category_attribute_value_pair = category_attribute + EQUALS + paren_list_value
event_attribute_value_pair = event_attribute + EQUALS + value
@@ -101,31 +150,36 @@ hint_attribute_value_pair = hint_attribute + EQUALS + value layout_attribute_value_pair = layout_attribute + EQUALS + value
generic_attribute_value_pair = attribute + EQUALS + value
attribute_value_pair << Group(
- category_attribute_value_pair
+ category_attribute_value_pair
| event_attribute_value_pair
| font_attribute_value_pair
| hint_attribute_value_pair
| layout_attribute_value_pair
| generic_attribute_value_pair
- )
+)
object_declaration = Group(OBJECT + object_name + COLON + object_type)
object_attributes = Group(ZeroOrMore(attribute_value_pair))
nested_object = Forward()
-object_definition = object_declaration + object_attributes + ZeroOrMore(nested_object) + END
+object_definition = (
+ object_declaration + object_attributes + ZeroOrMore(nested_object) + END
+)
nested_object << Group(object_definition)
#################
# END GRAMMAR
#################
+
def printer(s, loc, tok):
- print(tok, end=' ')
+ print(tok, end=" ")
return tok
+
def get_filename_list(tf):
import sys, glob
+
if tf == None:
if len(sys.argv) > 1:
tf = sys.argv[1:]
@@ -138,6 +192,7 @@ def get_filename_list(tf): testfiles.extend(glob.glob(arg))
return testfiles
+
def main(testfiles=None, action=printer):
"""testfiles can be None, in which case the command line arguments are used as filenames.
testfiles can be a string, in which case that file is parsed.
@@ -165,8 +220,8 @@ def main(testfiles=None, action=printer): failures.append(f)
if failures:
- print('\nfailed while processing %s' % ', '.join(failures))
- print('\nsucceeded on %d of %d files' %(success, len(testfiles)))
+ print("\nfailed while processing %s" % ", ".join(failures))
+ print("\nsucceeded on %d of %d files" % (success, len(testfiles)))
if len(retval) == 1 and len(testfiles) == 1:
# if only one file is parsed, return the parseResults directly
@@ -175,5 +230,6 @@ def main(testfiles=None, action=printer): # else, return a dictionary of parseResults
return retval
+
if __name__ == "__main__":
main()
|