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
|
from __future__ import annotations
from tatsu.tool import compile, gencode
def test_name_in_option():
grammar = r"""
start = expr_range ;
expr_range =
| [from: expr] '..' [to: expr]
| expr
;
expr =
/[\d]+/
;
"""
model = compile(grammar)
ast = model.parse('1 .. 10')
assert ast == {'from': '1', 'to': '10'}
ast = model.parse('10')
assert ast == '10'
ast = model.parse(' .. 10')
assert ast == {'from': None, 'to': '10'}
ast = model.parse('1 .. ')
assert ast == {'from': '1', 'to': None}
ast = model.parse(' .. ')
assert ast == {'from': None, 'to': None}
code = gencode(grammar=grammar)
print(code)
def test_by_option():
grammar = r"""
start = expr_range ;
expr_range =
| [from: expr] '..' [to: expr]
| left:expr ',' [right:expr]
;
expr =
/[\d]+/
;
"""
model = compile(grammar)
ast = model.parse(' .. 10')
assert ast == {'from': None, 'to': '10'}
ast = model.parse('1, 2')
assert ast == {'left': '1', 'right': '2'}
ast = model.parse('1, ')
assert ast == {'left': '1', 'right': None}
def test_inner_options():
grammar = """
start = switch;
switch = 'switch' [(on:'on'|off:'off')] ;
"""
model = compile(grammar)
ast = model.parse('switch on')
assert ast == {'on': 'on', 'off': None}
ast = model.parse('switch off')
assert ast == {'off': 'off', 'on': None}
ast = model.parse('switch')
assert ast == {'off': None, 'on': None}
|