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
|
import unittest
from tatsu.exceptions import FailedParse
from tatsu.ngcodegen import codegen
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))
print(codegen(model.rules[0].exp.sequence[0]))
self.assertEqual(
codegen(model.rules[0].exp.sequence[0]).strip(),
repr("self._pattern('(?x)\nfoo\nbar\n')").strip('"\''),
)
grammar = r"""
start =
/(?x)foo\nbar
blort/ $ ;
"""
model = compile(grammar=trim(grammar))
print(codegen(model.rules[0].exp.sequence[0]))
self.assertEqual(
trim(codegen(model.rules[0].exp.sequence[0])),
repr("self._pattern('(?x)foo\\nbar\nblort')").strip(r'"\.'),
)
|