diff options
author | ptmcg <ptmcg@austin.rr.com> | 2023-03-26 02:12:17 -0500 |
---|---|---|
committer | ptmcg <ptmcg@austin.rr.com> | 2023-03-26 02:12:17 -0500 |
commit | 9d789cbc7331509862060c8b06ebca9fe9d827b2 (patch) | |
tree | a4633437ce0a7e0baf784a6c4fa362e6eb748bfb | |
parent | 2e98055c8dab3e00fd20f39cd815b7e2773886e7 (diff) | |
download | pyparsing-git-9d789cbc7331509862060c8b06ebca9fe9d827b2.tar.gz |
Fix #475 - SkipTo used incorrect storage of ignore expressions, would match the target expression if present within an ignorable
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | pyparsing/core.py | 17 | ||||
-rw-r--r-- | tests/test_unit.py | 17 |
3 files changed, 27 insertions, 11 deletions
@@ -4,6 +4,10 @@ Change Log Version 3.1.0a2 - (in development) ---------------------------------- +Fixed bug in `SkipTo` where ignore expressions were not properly handled while +scanning for the target expression. Issue #475, reported by elkniwt, thanks +(this bug has been there for a looooong time!). + Updated ci.yml permissions to limit default access to source - submitted by Joyce Brum of Google. Thanks so much! diff --git a/pyparsing/core.py b/pyparsing/core.py index 02ae50a..b51779f 100644 --- a/pyparsing/core.py +++ b/pyparsing/core.py @@ -5281,7 +5281,8 @@ class SkipTo(ParseElementEnhance): ): super().__init__(other) failOn = failOn or fail_on - self.ignoreExpr = ignore + if ignore is not None: + self.ignore(ignore) self.mayReturnEmpty = True self.mayIndexError = False self.includeMatch = include @@ -5299,9 +5300,7 @@ class SkipTo(ParseElementEnhance): self_failOn_canParseNext = ( self.failOn.canParseNext if self.failOn is not None else None ) - self_ignoreExpr_tryParse = ( - self.ignoreExpr.try_parse if self.ignoreExpr is not None else None - ) + self_preParse = self.preParse if self.callPreparse else None tmploc = loc while tmploc <= instrlen: @@ -5310,13 +5309,9 @@ class SkipTo(ParseElementEnhance): if self_failOn_canParseNext(instring, tmploc): break - if self_ignoreExpr_tryParse is not None: - # advance past ignore expressions - while 1: - try: - tmploc = self_ignoreExpr_tryParse(instring, tmploc) - except ParseBaseException: - break + if self_preParse is not None: + # skip grammar-ignored expressions + tmploc = self_preParse(instring, tmploc) try: self_expr_parse(instring, tmploc, doActions=False, callPreParse=False) diff --git a/tests/test_unit.py b/tests/test_unit.py index c2a7160..0f1cb5a 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -1692,6 +1692,23 @@ class Test02_WithoutPackrat(ppt.TestParseResultsAsserts, TestCase): {"_skipped": ["red ", "456 "]}, ) + def testSkipToPreParseIgnoreExprs(self): + # added to verify fix to Issue #475 + from pyparsing import Word, alphanums, python_style_comment + + some_grammar = Word(alphanums) + ":=" + ... + ';' + some_grammar.ignore(python_style_comment) + try: + result = some_grammar.parse_string("""\ + var1 := 2 # 3; <== this semi-colon will match! + + 1; + """, parse_all=True) + except ParseException as pe: + print(pe.explain()) + raise + else: + print(result.dump()) + def testEllipsisRepetition(self): word = pp.Word(pp.alphas).setName("word") |