Mercurial > lbo > hg > pcombinators
changeset 7:b4844d42ed0f draft
Improve parsing of individual characters
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sun, 19 May 2019 14:31:40 +0200 |
parents | e4b519f95d2d |
children | 07dfebce36c5 |
files | arith_test.py combinators.py |
diffstat | 2 files changed, 14 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/arith_test.py Sun May 19 14:15:45 2019 +0200 +++ b/arith_test.py Sun May 19 14:31:40 2019 +0200 @@ -9,24 +9,29 @@ from combinators import * class Parens(Parser): + def parse(self, st): initial = st.index() + p1, st = Operator('(').parse(st) print('pr', p1, st) if p1 is None: st.reset(initial) return None, st + term, st = Term().parse(st) print('pr', term, st) if term is None: st.reset(initial) return None, st + p2, st = Operator(')').parse(st) print('pr', p2, st) if p2 is None: print('No closing paren!') st.reset(initial) return None, st + return term, st def Atom(): @@ -34,7 +39,8 @@ return (Float() | Parens() | Regex('\w+')) def Operator(set): - return Last(Skip(Whitespace()) + CharSet(set)) + """An operator or parenthesis.""" + return Last(Skip(Whitespace()) + OneOf(set)) class Product(Parser): @@ -91,6 +97,7 @@ return '({} {} {})'.format(pretty_print(tpl[0]), tpl[1], pretty_print(tpl[2])) def parse_and_print(expr): + """Parse an expression string and return a string of the parsing result.""" parsed, st = Term().parse(ps(expr)) if parsed is None: print('Parse error :(', st)
--- a/combinators.py Sun May 19 14:15:45 2019 +0200 +++ b/combinators.py Sun May 19 14:31:40 2019 +0200 @@ -272,7 +272,7 @@ st.reset(initial) return (None, st) -class CharSet(Parser): +class OneOf(Parser): """Parse characters in the given set. Result is string or None, if none were parsed.""" _set = None @@ -286,8 +286,8 @@ def parse(self, st): result = '' - while not st.finished() and st.peek() in self._set: - result += st.next() + if not st.finished() and st.peek() in self._set: + result = st.next() if len(result) == 0: return None, st return result, st @@ -318,6 +318,9 @@ # Small specific parsers. +def CharSet(s): + return Repeat(OneOf(s), -1) >> (lambda l: ''.join(l)) + def Integer(): """Return a parser that parses integers and results in an integer. Result is int.""" return Last(Whitespace() + (CharSet('0123456789') >> int))