summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorptmcg <ptmcg@austin.rr.com>2023-03-26 02:12:17 -0500
committerptmcg <ptmcg@austin.rr.com>2023-03-26 02:12:17 -0500
commit9d789cbc7331509862060c8b06ebca9fe9d827b2 (patch)
treea4633437ce0a7e0baf784a6c4fa362e6eb748bfb
parent2e98055c8dab3e00fd20f39cd815b7e2773886e7 (diff)
downloadpyparsing-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--CHANGES4
-rw-r--r--pyparsing/core.py17
-rw-r--r--tests/test_unit.py17
3 files changed, 27 insertions, 11 deletions
diff --git a/CHANGES b/CHANGES
index fd210a5..2886034 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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")