10.12., 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit a4f9cbe1 authored by Eckhart Arnold's avatar Eckhart Arnold

- syntaxtree.py: bug fix len values; LaTeX-example, new ebnf definition

parent 02269ca2
......@@ -191,11 +191,11 @@ class Node:
self._result = '' # type: StrictResultType
self._errors = [] # type: List[str]
self._children = () # type: Tuple['Node', ...]
self.result = result
self._len = len(self.result) if not self.children else \
sum(child._len for child in self.children) # type: int
# self.pos: int = 0 # continuous updating of pos values
self._pos = -1 # type: int
self.result = result
self.parser = parser or ZOMBIE_PARSER
self.error_flag = any(r.error_flag for r in self.children) \
if self.children else False # type: bool
......
......@@ -214,6 +214,7 @@ def grammar_unit(test_unit, parser_factory, transformer_factory, report=True, ve
unit_dir, unit_name = os.path.split(os.path.splitext(test_unit)[0])
test_unit = unit_from_file(test_unit)
else:
unit_dir = ""
unit_name = str(id(test_unit))
if verbose:
print("\nUnit: " + unit_name)
......
# latex Grammar
@ testing = True
@ whitespace = /[ \t]*\n?(?!\s*\n)[ \t]*/ # whitespace, including at most one linefeed
@ whitespace = /[ \t]*(?:\n(?![ \t]*\n)[ \t]*)?/ # optional whitespace, including at most one linefeed
@ comment = /%.*(?:\n|$)/
latexdoc = preamble document
......@@ -13,20 +13,18 @@ genericenv = beginenv sequence §endenv
beginenv = "\begin" §( "{" NAME "}" )
endenv = "\end" §( "{" ::NAME "}" )
command = CMDNAME [ config ] block
config = "[" cfgtext §"]"
parblock = "{" sequence §"}"
sequence = { partext | parblock }
sequence = { paragraph [PARSEP] }+
paragraph = { !blockcmd (command | block | text) }+
parblock = "{" paragraph §"}"
command = CMDNAME [ config ] block
config = "[" cfgtext §"]"
block = "{" { text | block } §"}"
paragraph = { partext | parblock }
partext = !blockcmd (text | PARSEP)
text = cfgtext | BRACKETS
cfgtext = word_sequence | ESCAPED | WSPC
word_sequence = { TEXTCHUNK }+
text = { cfgtext | (BRACKETS //~) }+
cfgtext = { word_sequence | (ESCAPED //~) }+
word_sequence = { TEXTCHUNK //~ }+
blockcmd = "\subsection" | "\section" | "\chapter" | "\subsubsection"
| "\paragraph" | "\subparagraph" | "\begin{enumerate}"
......@@ -39,9 +37,9 @@ ESCAPED = /\\[%$&]/
BRACKETS = /[\[\]]/ # left or right square bracket: [ ]
TEXTCHUNK = /[^\\%$&\{\}\[\]\s\n]+/ # some piece of text excluding whitespace,
# linefeed and special characters
WSPC = /[ \t]*\n?(?![ \t]*\n)[ \t]*/ # whitespace, including at most one linefeed
LF = /[ \t]*\n(?!\s*\n)/ # a linefeed, but not an empty line (i.e. par)
PARSEP = /\n[ \t]*(?=\n)/~ # at least one empty line, i.e.
WSPC = /[ \t]+/ # (horizontal) whitespace
LF = !PARSEP /[ \t]*\n[ \t]*/ # LF but not an empty line
PARSEP = /[ \t]*\n[ \t]*\n[ \t]*/ # at least one empty line, i.e.
# [whitespace] linefeed [whitespace] linefeed
EOF = !/./
......@@ -24,7 +24,9 @@ import sys
sys.path.extend(['../../', '../', './'])
from DHParser.toolkit import logging
from DHParser.testing import recompile_grammar
if not recompile_grammar('.', True):
sys.exit(1)
with logging():
if not recompile_grammar('.', True):
sys.exit(1)
......@@ -23,7 +23,7 @@ import copy
import sys
sys.path.extend(['../', './'])
from DHParser.syntaxtree import traverse, reduce_single_child, \
from DHParser.syntaxtree import Node, traverse, reduce_single_child, \
replace_by_single_child, flatten, remove_expendables, TOKEN_PTYPE
from DHParser.testing import mock_syntax_tree
from DHParser.ebnf import get_ebnf_grammar, get_ebnf_transformer, get_ebnf_compiler
......@@ -99,6 +99,19 @@ class TestNode:
res4 = compiler(tree)
assert res4 == res3
def test_len_and_pos(self):
"""Test len-property of Node."""
nd1 = Node(None, "123")
assert nd1.len == 3, "Expected Node.len == 3, got %i" % nd1.len
nd2 = Node(None, "456")
assert nd2.len == 3, "Expected Node.len == 3, got %i" % nd1.len
nd = Node(None, (nd1, nd2))
assert nd.len == 6, "Expected Node.len == 6, got %i" % nd.len
nd.pos = 0
assert nd.pos == 0, "Expected Node.pos == 0, got %i" % nd.pos
assert nd1.pos == 0, "Expected Node.pos == 0, got %i" % nd1.pos
assert nd2.pos == 3, "Expected Node.pos == 3, got %i" % nd2.pos
class TestErrorHandling:
def test_error_flag_propagation(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment