1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
# Copyright (c) 2017-2026 Juancarlo AƱez (apalala@gmail.com)
# SPDX-License-Identifier: BSD-4-Clause
from __future__ import annotations
import unittest
from tatsu.exceptions import FailedParse
from tatsu.ngcodegen import pythongen
from tatsu.tool import compile
from tatsu.util import trim
class PatternTests(unittest.TestCase):
def test_patterns_with_newlines(self):
grammar = """
@@whitespace :: /[ \t]/
start
=
blanklines $
;
blanklines
=
blankline [blanklines]
;
blankline
=
/(?m)^[^\\n]*\\n$/
;
"""
model = compile(grammar, 'test')
ast = model.parse('\n\n')
self.assertEqual(('\n', '\n'), ast)
def test_pattern_concatenation(self):
grammar = """
start
=
{letters_digits}+
;
letters_digits
=
?"[a-z]+"
+ ?'[0-9]+'
;
"""
pretty = """
start
=
{letters_digits}+
;
letters_digits
=
/[a-z]+/
+ /[0-9]+/
;
"""
model = compile(grammar=grammar)
ast = model.parse('abc123 def456')
self.assertEqual(['abc123', 'def456'], ast)
print(model.pretty())
self.assertEqual(trim(pretty), model.pretty())
def test_ignorecase_not_for_pattern(self):
grammar = """
@@ignorecase
start
=
{word} $
;
word
=
/[a-z]+/
;
"""
model = compile(grammar=grammar)
try:
model.parse('ABcD xYZ')
self.fail('@@ignorecase should not apply to patterns')
except FailedParse:
pass
def test_ignorecase_pattern(self):
grammar = """
start
=
{word} $
;
word
=
/(?i)[a-z]+/
;
"""
model = compile(grammar=grammar)
ast = model.parse('ABcD xYZ')
self.assertEqual(['ABcD', 'xYZ'], ast)
def test_multiline_pattern(self):
grammar = r"""
start =
/(?x)
foo
bar
/ $ ;
"""
model = compile(grammar=trim(grammar))
from tatsu import grammars
assert isinstance(model.rules[0].exp, grammars.Sequence)
print(pythongen(model.rules[0].exp.sequence[0]))
self.assertEqual(
pythongen(model.rules[0].exp.sequence[0]).strip(),
"self._pattern(r'(?x)\\nfoo\\nbar\\n')",
)
grammar = r"""
start =
/(?x)foo\nbar
blort/ $ ;
"""
model = compile(grammar=trim(grammar))
assert isinstance(model.rules[0].exp, grammars.Sequence)
print(pythongen(model.rules[0].exp.sequence[0]))
self.assertEqual(
trim(pythongen(model.rules[0].exp.sequence[0])),
"self._pattern(r'(?x)foo\\nbar\\nblort')",
)
|