diff options
author | Paul McGuire <ptmcg@austin.rr.com> | 2019-08-05 22:07:15 -0500 |
---|---|---|
committer | Paul McGuire <ptmcg@austin.rr.com> | 2019-08-05 22:07:15 -0500 |
commit | 9ca5931db90a487085851fd9f847066fd48ae55b (patch) | |
tree | 9dcdb6fb3bd842120b666c470b9206be237574a1 | |
parent | 10b5e96bda409e6ecd895fe41f65cc9bd943b824 (diff) | |
download | pyparsing-git-9ca5931db90a487085851fd9f847066fd48ae55b.tar.gz |
Code style updates; remove deprecated methods
-rw-r--r-- | examples/romanNumerals.py | 156 | ||||
-rw-r--r-- | examples/rosettacode.py | 7 | ||||
-rw-r--r-- | examples/shapes.py | 128 |
3 files changed, 147 insertions, 144 deletions
diff --git a/examples/romanNumerals.py b/examples/romanNumerals.py index 8765055..6e675a9 100644 --- a/examples/romanNumerals.py +++ b/examples/romanNumerals.py @@ -1,77 +1,79 @@ -# romanNumerals.py
-#
-# Copyright (c) 2006, Paul McGuire
-#
-
-from pyparsing import *
-
-def romanNumeralLiteral(numeralString, value):
- return Literal(numeralString).setParseAction(replaceWith(value))
-
-one = romanNumeralLiteral("I",1)
-four = romanNumeralLiteral("IV",4)
-five = romanNumeralLiteral("V",5)
-nine = romanNumeralLiteral("IX",9)
-ten = romanNumeralLiteral("X",10)
-forty = romanNumeralLiteral("XL",40)
-fifty = romanNumeralLiteral("L",50)
-ninety = romanNumeralLiteral("XC",90)
-onehundred = romanNumeralLiteral("C",100)
-fourhundred = romanNumeralLiteral("CD",400)
-fivehundred = romanNumeralLiteral("D",500)
-ninehundred = romanNumeralLiteral("CM",900)
-onethousand = romanNumeralLiteral("M",1000)
-
-numeral = ( onethousand | ninehundred | fivehundred | fourhundred |
- onehundred | ninety | fifty | forty | ten | nine | five |
- four | one ).leaveWhitespace()
-
-romanNumeral = OneOrMore(numeral).setParseAction( lambda s,l,t : sum(t) )
-
-# unit tests
-def makeRomanNumeral(n):
- def addDigit(n,limit,c,s):
- n -= limit
- s += c
- return n,s
-
- ret = ""
- while n >= 1000: n,ret = addDigit(n,1000,"M",ret)
- while n >= 900: n,ret = addDigit(n, 900,"CM",ret)
- while n >= 500: n,ret = addDigit(n, 500,"D",ret)
- while n >= 400: n,ret = addDigit(n, 400,"CD",ret)
- while n >= 100: n,ret = addDigit(n, 100,"C",ret)
- while n >= 90: n,ret = addDigit(n, 90,"XC",ret)
- while n >= 50: n,ret = addDigit(n, 50,"L",ret)
- while n >= 40: n,ret = addDigit(n, 40,"XL",ret)
- while n >= 10: n,ret = addDigit(n, 10,"X",ret)
- while n >= 9: n,ret = addDigit(n, 9,"IX",ret)
- while n >= 5: n,ret = addDigit(n, 5,"V",ret)
- while n >= 4: n,ret = addDigit(n, 4,"IV",ret)
- while n >= 1: n,ret = addDigit(n, 1,"I",ret)
- return ret
-tests = " ".join(makeRomanNumeral(i) for i in range(1,5000+1))
-
-roman_int_map = {}
-expected = 1
-for t,s,e in romanNumeral.scanString(tests):
- orig = tests[s:e]
- if t[0] != expected:
- print("{0} {1} {2}".format("==>", t, orig))
- roman_int_map[orig] = t[0]
- expected += 1
-
-def verify_value(s, tokens):
- expected = roman_int_map[s]
- if tokens[0] != expected:
- raise Exception("incorrect value for {0} ({1}), expected {2}".format(s, tokens[0], expected ))
-
-romanNumeral.runTests("""\
- XVI
- XXXIX
- XIV
- XIX
- MCMLXXX
- MMVI
- """, fullDump=False,
- postParse=verify_value)
\ No newline at end of file +# romanNumerals.py +# +# Copyright (c) 2006, 2019, Paul McGuire +# + +import pyparsing as pp + +def romanNumeralLiteral(numeralString, value): + return pp.Literal(numeralString).setParseAction(pp.replaceWith(value)) + +one = romanNumeralLiteral("I", 1) +four = romanNumeralLiteral("IV", 4) +five = romanNumeralLiteral("V", 5) +nine = romanNumeralLiteral("IX", 9) +ten = romanNumeralLiteral("X", 10) +forty = romanNumeralLiteral("XL", 40) +fifty = romanNumeralLiteral("L", 50) +ninety = romanNumeralLiteral("XC", 90) +onehundred = romanNumeralLiteral("C", 100) +fourhundred = romanNumeralLiteral("CD", 400) +fivehundred = romanNumeralLiteral("D", 500) +ninehundred = romanNumeralLiteral("CM", 900) +onethousand = romanNumeralLiteral("M", 1000) + +numeral = (onethousand | ninehundred | fivehundred | fourhundred + | onehundred | ninety | fifty | forty | ten | nine | five + | four | one).leaveWhitespace() + +romanNumeral = numeral[1, ...].setParseAction(sum) + +# unit tests +def makeRomanNumeral(n): + def addDigits(n, limit, c, s): + while n > limit: + n -= limit + s += c + return n, s + + ret = "" + n, ret = addDigits(n, 1000, "M", ret) + n, ret = addDigits(n, 900, "CM", ret) + n, ret = addDigits(n, 500, "D", ret) + n, ret = addDigits(n, 400, "CD", ret) + n, ret = addDigits(n, 100, "C", ret) + n, ret = addDigits(n, 90, "XC", ret) + n, ret = addDigits(n, 50, "L", ret) + n, ret = addDigits(n, 40, "XL", ret) + n, ret = addDigits(n, 10, "X", ret) + n, ret = addDigits(n, 9, "IX", ret) + n, ret = addDigits(n, 5, "V", ret) + n, ret = addDigits(n, 4, "IV", ret) + n, ret = addDigits(n, 1, "I", ret) + return ret + +# make a string of all roman numerals from I to MMMMM +tests = " ".join(makeRomanNumeral(i) for i in range(1, 5000+1)) + +# parse each roman numeral, and populate map for validation below +roman_int_map = {} +for expected, (t, s, e) in enumerate(romanNumeral.scanString(tests), start=1): + orig = tests[s:e] + if t[0] != expected: + print("{0} {1} {2}".format("==>", t, orig)) + roman_int_map[orig] = t[0] + +def verify_value(s, tokens): + expected = roman_int_map[s] + if tokens[0] != expected: + raise Exception("incorrect value for {0} ({1}), expected {2}".format(s, tokens[0], expected )) + +romanNumeral.runTests("""\ + XVI + XXXIX + XIV + XIX + MCMLXXX + MMVI + """, fullDump=False, + postParse=verify_value) diff --git a/examples/rosettacode.py b/examples/rosettacode.py index 07ed7fa..8a8d5c9 100644 --- a/examples/rosettacode.py +++ b/examples/rosettacode.py @@ -41,7 +41,8 @@ LBRACE, RBRACE, LPAR, RPAR, SEMI = map(pp.Suppress, "{}();") EQ = pp.Literal('=') keywords = (WHILE, IF, PRINT, PUTC, ELSE) = map(pp.Keyword, "while if print putc else".split()) -identifier = ~(pp.MatchFirst(keywords)) + pp.pyparsing_common.identifier +any_keyword = pp.MatchFirst(keywords) +identifier = ~any_keyword + pp.pyparsing_common.identifier integer = pp.pyparsing_common.integer string = pp.QuotedString('"', convertWhitespaceEscapes=False).setName("quoted string") char = pp.Regex(r"'\\?.'") @@ -66,7 +67,7 @@ while_stmt = pp.Group(WHILE - paren_expr + stmt) if_stmt = pp.Group(IF - paren_expr + stmt + pp.Optional(ELSE + stmt)) print_stmt = pp.Group(PRINT - pp.Group(LPAR + prt_list + RPAR) + SEMI) putc_stmt = pp.Group(PUTC - paren_expr + SEMI) -stmt_list = pp.Group(LBRACE + pp.ZeroOrMore(stmt) + RBRACE) +stmt_list = pp.Group(LBRACE + stmt[...] + RBRACE) stmt <<= (pp.Group(SEMI) | assignment_stmt | while_stmt @@ -76,7 +77,7 @@ stmt <<= (pp.Group(SEMI) | stmt_list ).setName("statement") -code = pp.ZeroOrMore(stmt) +code = stmt[...] code.ignore(pp.cppStyleComment) diff --git a/examples/shapes.py b/examples/shapes.py index 2df8572..55af19a 100644 --- a/examples/shapes.py +++ b/examples/shapes.py @@ -1,64 +1,64 @@ -# shapes.py
-#
-# A sample program showing how parse actions can convert parsed
-# strings into a data type or object.
-#
-# Copyright 2012, Paul T. McGuire
-#
-
-# define class hierarchy of Shape classes, with polymorphic area method
-class Shape(object):
- def __init__(self, tokens):
- self.__dict__.update(tokens.asDict())
-
- def area(self):
- raise NotImplementedException()
-
- def __str__(self):
- return "<{0}>: {1}".format(self.__class__.__name__, self.__dict__)
-
-class Square(Shape):
- def area(self):
- return self.side**2
-
-class Rectangle(Shape):
- def area(self):
- return self.width * self.height
-
-class Circle(Shape):
- def area(self):
- return 3.14159 * self.radius**2
-
-
-from pyparsing import *
-
-number = Regex(r'-?\d+(\.\d*)?').setParseAction(lambda t:float(t[0]))
-
-# Shape expressions:
-# square : S <centerx> <centery> <side>
-# rectangle: R <centerx> <centery> <width> <height>
-# circle : C <centerx> <centery> <diameter>
-
-squareDefn = "S" + number('centerx') + number('centery') + number('side')
-rectDefn = "R" + number('centerx') + number('centery') + number('width') + number('height')
-circleDefn = "C" + number('centerx') + number('centery') + number('diameter')
-
-squareDefn.setParseAction(Square)
-rectDefn.setParseAction(Rectangle)
-
-def computeRadius(tokens):
- tokens['radius'] = tokens.diameter/2.0
-circleDefn.setParseAction(computeRadius, Circle)
-
-shapeExpr = squareDefn | rectDefn | circleDefn
-
-tests = """\
-C 0 0 100
-R 10 10 20 50
-S -1 5 10""".splitlines()
-
-for t in tests:
- shape = shapeExpr.parseString(t)[0]
- print(shape)
- print("Area:", shape.area())
- print()
+# shapes.py +# +# A sample program showing how parse actions can convert parsed +# strings into a data type or object. +# +# Copyright 2012, 2019 Paul T. McGuire +# + +# define class hierarchy of Shape classes, with polymorphic area method +class Shape(object): + def __init__(self, tokens): + self.__dict__.update(tokens.asDict()) + + def area(self): + raise NotImplemented() + + def __str__(self): + return "<{0}>: {1}".format(self.__class__.__name__, vars(self)) + +class Square(Shape): + def area(self): + return self.side**2 + +class Rectangle(Shape): + def area(self): + return self.width * self.height + +class Circle(Shape): + def area(self): + return 3.14159 * self.radius**2 + + +import pyparsing as pp + +number = pp.Regex(r'-?\d+(\.\d*)?').setParseAction(lambda t: float(t[0])) + +# Shape expressions: +# square : S <centerx> <centery> <side> +# rectangle: R <centerx> <centery> <width> <height> +# circle : C <centerx> <centery> <diameter> + +squareDefn = "S" + number('centerx') + number('centery') + number('side') +rectDefn = "R" + number('centerx') + number('centery') + number('width') + number('height') +circleDefn = "C" + number('centerx') + number('centery') + number('diameter') + +squareDefn.setParseAction(Square) +rectDefn.setParseAction(Rectangle) + +def computeRadius(tokens): + tokens['radius'] = tokens.diameter/2.0 +circleDefn.setParseAction(computeRadius, Circle) + +shapeExpr = squareDefn | rectDefn | circleDefn + +tests = """\ +C 0 0 100 +R 10 10 20 50 +S -1 5 10""".splitlines() + +for t in tests: + shape = shapeExpr.parseString(t)[0] + print(shape) + print("Area:", shape.area()) + print() |