Skip to content

Commit

Permalink
Fix #475 - SkipTo used incorrect storage of ignore expressions, would…
Browse files Browse the repository at this point in the history
… match the target expression if present within an ignorable
  • Loading branch information
ptmcg committed Mar 26, 2023
1 parent 2e98055 commit 9d789cb
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGES
Expand Up @@ -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!

Expand Down
17 changes: 6 additions & 11 deletions pyparsing/core.py
Expand Up @@ -5281,7 +5281,8 @@ def __init__(
):
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
Expand All @@ -5299,9 +5300,7 @@ def parseImpl(self, instring, loc, doActions=True):
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:
Expand All @@ -5310,13 +5309,9 @@ def parseImpl(self, instring, loc, doActions=True):
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)
Expand Down
17 changes: 17 additions & 0 deletions tests/test_unit.py
Expand Up @@ -1692,6 +1692,23 @@ def test(expr, test_string, expected_list, expected_dict):
{"_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")
Expand Down

0 comments on commit 9d789cb

Please sign in to comment.