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

Commit c90f13a2 authored by Eckhart Arnold's avatar Eckhart Arnold
Browse files

- remove_children_if optimized

parent 5ec9ebc8
......@@ -212,14 +212,13 @@ def traverse(root_node: Node,
table = processing_table
cache = processing_table['__cache__']
else:
# normalize processing_table entries by turning single values into lists
# with a single value
# normalize processing_table entries by turning single values
# into lists with a single value
table = {name: smart_list(call) for name, call in list(processing_table.items())}
table = expand_table(table)
cache = table.setdefault('__cache__', {}) # type: Dict[str, List[Callable]]
# change processing table in place, so that table expansion does not get lost
# between calls
processing_table.clear();
# change processing table in place, so its already expanded and cache filled next time
processing_table.clear()
processing_table.update(table)
# assert '__cache__' in processing_table
......@@ -238,8 +237,9 @@ def traverse(root_node: Node,
context.pop()
key = key_func(node)
sequence = cache.get(key, None)
if sequence is None:
try:
sequence = cache[key]
except KeyError:
sequence = table.get('+', []) + \
table.get(key, table.get('*', [])) + \
table.get('~', [])
......@@ -494,6 +494,14 @@ def keep_children(context: List[Node], section: slice = slice(None)):
@transformation_factory(Callable)
def remove_children_if(context: List[Node], condition: Callable, section: slice = slice(None)):
"""Removes all children for which `condition()` returns `True`."""
node = context[-1]
if node.children:
node.result = tuple(c for c in node.children if not condition(context + [c]))
@transformation_factory(Callable)
def remove_children(context: List[Node], condition: Callable, section: slice = slice(None)):
"""Removes all nodes from a slice of the result field if the function
`condition(child_node)` evaluates to `True`."""
node = context[-1]
......
......@@ -71,15 +71,16 @@ verbatim = "\begin{verbatim}" sequence §"\end{verbatim}"
tabular = "\begin{tabular}" tabular_config { tabular_row } §"\end{tabular}"
tabular_row = (multicolumn | tabular_cell) { "&" (multicolumn | tabular_cell) }
"\\" ( hline | { cline } )
tabular_cell = { text_element //~ }
tabular_cell = { line_element //~ }
tabular_config = "{" /[lcr|]+/~ §"}"
#### paragraphs and sequences of paragraphs ####
block_of_paragraphs = "{" [sequence] §"}"
sequence = { (paragraph | block_environment ) [PARSEP] }+
paragraph = { !blockcmd (text_element | LINEFEED) //~ }+
text_element = text | block | inline_environment | command
paragraph = { !blockcmd text_element //~ }+
text_element = line_element | LINEFEED
line_element = text | block | inline_environment | command
#### inline enivronments ####
......
......@@ -120,15 +120,16 @@ class LaTeXGrammar(Grammar):
tabular = "\begin{tabular}" tabular_config { tabular_row } §"\end{tabular}"
tabular_row = (multicolumn | tabular_cell) { "&" (multicolumn | tabular_cell) }
"\\" ( hline | { cline } )
tabular_cell = { text_element //~ }
tabular_cell = { line_element //~ }
tabular_config = "{" /[lcr|]+/~ §"}"
#### paragraphs and sequences of paragraphs ####
block_of_paragraphs = "{" [sequence] §"}"
sequence = { (paragraph | block_environment ) [PARSEP] }+
paragraph = { !blockcmd (text_element | LINEFEED) //~ }+
text_element = text | block | inline_environment | command
paragraph = { !blockcmd text_element //~ }+
text_element = line_element | LINEFEED
line_element = text | block | inline_environment | command
#### inline enivronments ####
......@@ -219,7 +220,7 @@ class LaTeXGrammar(Grammar):
paragraph = Forward()
tabular_config = Forward()
text_element = Forward()
source_hash__ = "e493869bdc02eb835ec3ce1ebfb0a4ea"
source_hash__ = "1d9bad5194b49edf88a447f370541ed1"
parser_initialization__ = "upon instantiation"
COMMENT__ = r'%.*(?:\n|$)'
WSP__ = mixin_comment(whitespace=r'[ \t]*(?:\n(?![ \t]*\n)[ \t]*)?', comment=r'%.*(?:\n|$)')
......@@ -267,12 +268,13 @@ class LaTeXGrammar(Grammar):
generic_inline_env = Series(begin_inline_env, RE(''), paragraph, Required(end_inline_env))
known_inline_env = Synonym(inline_math)
inline_environment = Alternative(known_inline_env, generic_inline_env)
text_element.set(Alternative(text, block, inline_environment, command))
paragraph.set(OneOrMore(Series(NegativeLookahead(blockcmd), Alternative(text_element, LINEFEED), RE(''))))
line_element = Alternative(text, block, inline_environment, command)
text_element.set(Alternative(line_element, LINEFEED))
paragraph.set(OneOrMore(Series(NegativeLookahead(blockcmd), text_element, RE(''))))
sequence = OneOrMore(Series(Alternative(paragraph, block_environment), Optional(PARSEP)))
block_of_paragraphs.set(Series(Token("{"), Optional(sequence), Required(Token("}"))))
tabular_config.set(Series(Token("{"), RE('[lcr|]+'), Required(Token("}"))))
tabular_cell = ZeroOrMore(Series(text_element, RE('')))
tabular_cell = ZeroOrMore(Series(line_element, RE('')))
tabular_row = Series(Alternative(multicolumn, tabular_cell),
ZeroOrMore(Series(Token("&"), Alternative(multicolumn, tabular_cell))),
Token("\\\\"), Alternative(hline, ZeroOrMore(cline)))
......
......@@ -19,14 +19,16 @@ See the License for the specific language governing permissions and
limitations under the License.
"""
import cProfile as profile
import os
import pstats
import sys
sys.path.extend(['../../', '../', './'])
import DHParser.dsl
from DHParser import toolkit
sys.path.extend(['../../', '../', './'])
if not DHParser.dsl.recompile_grammar('LaTeX.ebnf', force=False): # recompiles Grammar only if it has changed
print('\nErrors while recompiling "LaTeX.ebnf":\n--------------------------------------\n\n')
with open('LaTeX_ebnf_ERRORS.txt') as f:
......@@ -46,18 +48,24 @@ def fail_on_error(src, result):
print(e)
sys.exit(1)
with toolkit.logging(True):
with toolkit.logging(False):
files = os.listdir('testdata')
files.sort()
pr = profile.Profile()
pr.enable()
for file in files:
if file.lower().endswith('.tex'):
if file.lower().endswith('.tex') and file.lower().find('error') < 0:
with open(os.path.join('testdata', file), 'r') as f:
doc = f.read()
print('\n\nParsing document: "%s"\n' % file)
result = parser(doc)
parser.log_parsing_history__()
fail_on_error(doc, result)
ast = transformer(result)
fail_on_error(doc, ast)
print(ast.as_sxpr())
transformer(result)
fail_on_error(doc, result)
print(result.as_sxpr())
pr.disable()
st = pstats.Stats(pr)
st.strip_dirs()
st.sort_stats('time').print_stats(20)
......@@ -21,10 +21,9 @@ limitations under the License.
import sys
import DHParser.dsl
sys.path.extend(['../../', '../', './'])
import DHParser.dsl
from DHParser import testing
from DHParser import toolkit
......
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