Added semantics for pairing blocks together

This required us to modify how the parser works so that once it
detects a pair of blocks, it kicks it back to our specific function
which allows us to detect if the pair of blocks it detected were a
matching pair. This is required in order to allow single blocks to
be included within paired blocks, as otherwise it would always match
the last single block to the end block.

This required changing the grammar so the pair blocks had their own
named expression. This allows us to reject the parse as invalid with
incorrect semantics and allows it to try to just parse the first
block alone.
This commit is contained in:
Kevin 2020-05-12 21:27:40 -04:00
parent 9cf1c578d4
commit 00e950e831
2 changed files with 26 additions and 3 deletions

View File

@ -39,8 +39,18 @@ raw_block_end
block_expression
=
| ( start:block_start contents:expressions end:block_end )
| block:block_start
| block_expression_pair
| block_expression_single
;
block_expression_pair
=
start:block_start contents:expressions end:block_end
;
block_expression_single
=
block:block_start
;
block_start

View File

@ -1,4 +1,5 @@
from datetime import datetime
from tatsu.exceptions import FailedSemantics
from tatsu.util import asjson
import json
import pprint
@ -8,6 +9,18 @@ from new_parser import parse_template
from jinja2.environment import Environment
class JinjaSemantics(object):
def block_expression_pair(self, ast):
start_block = ast['start']
end_block = ast['end']
if start_block['name'] != end_block['name']:
raise FailedSemantics()
return ast
with open('grammar.ebnf', 'r') as tatsu_grammar:
with open('test_template.jinja', 'r') as test_template:
template_string = test_template.read()
@ -20,7 +33,7 @@ with open('grammar.ebnf', 'r') as tatsu_grammar:
parse_start = datetime.now()
ast = grammar.parse(template_string, whitespace='', parseinfo=True)
ast = grammar.parse(template_string, whitespace='', parseinfo=True, semantics=JinjaSemantics())
parse_end = datetime.now()