diff options
author | da-woods <dw-git@d-woods.co.uk> | 2022-06-18 10:10:02 +0100 |
---|---|---|
committer | da-woods <dw-git@d-woods.co.uk> | 2022-06-18 10:10:02 +0100 |
commit | 2277c3345ed81770166a0f457c77e3b01b26f994 (patch) | |
tree | b11e694dcec8f145fc375062839ad0646a3644f1 | |
parent | 7c9f67910babad0efcf31960db1513ac398cb4b2 (diff) | |
download | cython-2277c3345ed81770166a0f457c77e3b01b26f994.tar.gz |
Improve pattern identification
Some types of pattern are unambiguous so don't need backtracking
-rw-r--r-- | Cython/Compiler/Parsing.py | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index a08abe66d..1cd67f445 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -4073,6 +4073,7 @@ def p_pattern(s): def p_closed_pattern(s): """ + The PEG parser specifies it as | literal_pattern | capture_pattern | wildcard_pattern @@ -4081,7 +4082,29 @@ def p_closed_pattern(s): | sequence_pattern | mapping_pattern | class_pattern + + For the sake avoiding too much backtracking, we know: + * starts with "{" is a sequence_pattern + * starts with "[" is a mapping_pattern + * starts with "(" is a group_pattern or sequence_pattern + * wildcard pattern is just identifier=='_' + The rest are then tried in order with backtracking """ + if s.sy == 'IDENT' and s.systring == '_': + pos = s.position() + s.next() + return MatchCaseNodes.MatchAndAssignPatternNode(pos) + elif s.sy == '{': + return p_mapping_pattern(s) + elif s.sy == '[': + return p_sequence_pattern(s) + elif s.sy == '(': + with tentatively_scan(s) as errors: + result = p_group_pattern(s) + if not errors: + return result + return p_sequence_pattern(s) + with tentatively_scan(s) as errors: result = p_literal_pattern(s) if not errors: @@ -4091,25 +4114,9 @@ def p_closed_pattern(s): if not errors: return result with tentatively_scan(s) as errors: - result = p_wildcard_pattern(s) - if not errors: - return result - with tentatively_scan(s) as errors: result = p_value_pattern(s) if not errors: return result - with tentatively_scan(s) as errors: - result = p_group_pattern(s) - if not errors: - return result - with tentatively_scan(s) as errors: - result = p_sequence_pattern(s) - if not errors: - return result - with tentatively_scan(s) as errors: - result = p_mapping_pattern(s) - if not errors: - return result return p_class_pattern(s) def p_literal_pattern(s): @@ -4224,13 +4231,6 @@ def p_group_pattern(s): s.expect(")") return pattern -def p_wildcard_pattern(s): - if s.sy != "IDENT" or s.systring != "_": - s.error("Expected '_'") - pos = s.position() - s.next() - return MatchCaseNodes.MatchAndAssignPatternNode(pos) - def p_sequence_pattern(s): opener = s.sy pos = s.position() |