Commit e0512e77 authored by Eckhart Arnold's avatar Eckhart Arnold

- code reorganization, bug fixes, further tests

parent 0cf9ea37
......@@ -21,7 +21,6 @@ Module ``DSLsupport`` contains various functions to support the
compilation of domain specific languages based on an EBNF-grammar.
"""
from functools import partial
import collections
import os
try:
......
......@@ -240,6 +240,7 @@ class EBNFCompiler(CompilerBase):
if 'right' in self.directives['literalws'] else "''"))
definitions.append(('wspL__', WHITESPACE_KEYWORD
if 'left' in self.directives['literalws'] else "''"))
print(self.directives) ####
definitions.append((WHITESPACE_KEYWORD,
("mixin_comment(whitespace="
"r'{whitespace}', comment=r'{comment}')").
......
......@@ -368,17 +368,6 @@ def error_messages(text, errors):
for err in sorted(list(errors)))
def compact_sexpr(s):
"""Returns S-expression ``s`` as a one liner without unnecessary
whitespace.
Example:
>>> compact_sexpr("(a\n (b\n c\n )\n)\n")
(a (b c))
"""
return re.sub('\s(?=\))', '', re.sub('\s+', ' ', s)).strip()
########################################################################
#
# syntax tree transformation functions
......
......@@ -118,6 +118,17 @@ def line_col(text, pos):
return line, column
def compact_sexpr(s):
"""Returns S-expression ``s`` as a one liner without unnecessary
whitespace.
Example:
>>> compact_sexpr("(a\n (b\n c\n )\n)\n")
(a (b c))
"""
return re.sub('\s(?=\))', '', re.sub('\s+', ' ', s)).strip()
def escape_re(s):
"""Returns `s` with all regular expression special characters escaped.
"""
......
DHParser
========
A parser combinator based parsing and compiling infrastructure for domain
A parser-combinator-based parsing and compiling infrastructure for domain
specific languages (DSL) in Digital Humanities projects.
Author: Eckhart Arnold, Bavarian Academy of Sciences
......@@ -32,8 +32,8 @@ parser generators, but employs the more modern form called
recursive descent parser.
Why another parser generator? There are plenty of good parser
generators out there,
e.g. [Añez's grako parser generator][Añez_2017]. However, DHParser is
generators out there, e.g. [Añez's grako parser generator][Añez_2017],
[Eclipse XText][XText_Website]. However, DHParser is
intended as a tool that is specifically geared towards digital
humanities applications, while most existing parser generators come
from compiler construction toolkits for programming languages. Also,
......@@ -157,3 +157,5 @@ München 2016. Short-URL: [tiny.badw.de/2JVy][Müller_2016]
[tex_stackexchange_no_bnf]: http://tex.stackexchange.com/questions/4201/is-there-a-bnf-grammar-of-the-tex-language
[tex_stackexchange_latex_parsers]: http://tex.stackexchange.com/questions/4223/what-parsers-for-latex-mathematics-exist-outside-of-the-tex-engines
[XText_website]: https://www.eclipse.org/Xtext/
EBNF
====
This directory contains one or more variants of grammars for the Extended
Backus-Naur-Form (EBNF). The file named 'EBNF.ebnf' should always be the grammar
for the stock EBNF-compiler of `ParserCombinators`.
......@@ -23,7 +23,7 @@ limitations under the License.
import os
import sys
sys.path.append(os.path.abspath('../../'))
from DHParser.DSLsupport import compileEBNF, run_compiler, source_changed
from DHParser.DSLsupport import compileEBNF
WRITE_LOGS = True
......@@ -66,3 +66,8 @@ class TestPopRetrieve:
if WRITE_LOGS:
syntax_tree.log("test_PopRetrieve_multi_line", '.cst')
self.minilang_parser.log_parsing_history("test_PopRetrieve_multi_line")
if __name__ == "__main__":
from run import run_tests
run_tests("TestPopRetrieve", globals())
\ No newline at end of file
#!/usr/bin/python3
"""test_parsercombinators.py - tests of the parsercombinators-module
of DHParser
Author: Eckhart Arnold <arnold@badw.de>
Copyright 2017 Bavarian Academy of Sciences and Humanities
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import os
import sys
sys.path.append(os.path.abspath('../../'))
from DHParser.DSLsupport import compileEBNF
WRITE_LOGS = True
class TestLeftRecursion:
mini_language1 = """
@ whitespace = linefeed
formula = expr "."
expr = expr ("+"|"-") term | term
term = term ("*"|"/") factor | factor
factor = /[0-9]+/
# example: "5 + 3 * 4"
"""
def setup(self):
self.minilang_parser1 = compileEBNF(self.mini_language1)()
def test_compile_mini_language(self):
assert self.minilang_parser1
def test_direct_left_recursion(self):
syntax_tree = self.minilang_parser1.parse("5 + 3 * 4")
assert not syntax_tree.collect_errors()
if WRITE_LOGS:
syntax_tree.log("test_LeftRecursion_direct", '.cst')
self.minilang_parser1.log_parsing_history("test_LeftRecursion_direct")
def test_indirect_left_recursion(self):
pass
if __name__ == "__main__":
from run import run_tests
run_tests("TestLeftRecursion", globals())
\ No newline at end of file
......@@ -24,7 +24,8 @@ import os
import re
import sys
sys.path.append(os.path.abspath('../../'))
from DHParser.syntaxtree import Node, compact_sexpr
from DHParser.toolkit import compact_sexpr
from DHParser.syntaxtree import Node
class DummyParser:
def __init__(self, name=''):
......@@ -116,4 +117,4 @@ class TestNode:
if __name__ == "__main__":
from run import run_tests
run_tests("TestNode", globals())
run_tests("TestSExpr TestNode", globals())
This diff is collapsed.
<?xml version="1.0" standalone="yes"?>
<!-- logreq request file -->
<!-- logreq version 1.0 / dtd version 1.0 -->
<!-- Do not edit this file! -->
<!DOCTYPE requests [
<!ELEMENT requests (internal | external)*>
<!ELEMENT internal (generic, (provides | requires)*)>
<!ELEMENT external (generic, cmdline?, input?, output?, (provides | requires)*)>
<!ELEMENT cmdline (binary, (option | infile | outfile)*)>
<!ELEMENT input (file)+>
<!ELEMENT output (file)+>
<!ELEMENT provides (file)+>
<!ELEMENT requires (file)+>
<!ELEMENT generic (#PCDATA)>
<!ELEMENT binary (#PCDATA)>
<!ELEMENT option (#PCDATA)>
<!ELEMENT infile (#PCDATA)>
<!ELEMENT outfile (#PCDATA)>
<!ELEMENT file (#PCDATA)>
<!ATTLIST requests
version CDATA #REQUIRED
>
<!ATTLIST internal
package CDATA #REQUIRED
priority (9) #REQUIRED
active (0 | 1) #REQUIRED
>
<!ATTLIST external
package CDATA #REQUIRED
priority (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8) #REQUIRED
active (0 | 1) #REQUIRED
>
<!ATTLIST provides
type (static | dynamic | editable) #REQUIRED
>
<!ATTLIST requires
type (static | dynamic | editable) #REQUIRED
>
<!ATTLIST file
type CDATA #IMPLIED
>
]>
<requests version="1.0">
<internal package="biblatex" priority="9" active="1">
<generic>latex</generic>
<provides type="dynamic">
<file>testdoc1.bcf</file>
</provides>
<requires type="dynamic">
<file>testdoc1.bbl</file>
</requires>
<requires type="static">
<file>blx-dm.def</file>
<file>blx-compat.def</file>
<file>biblatex.def</file>
<file>blx-natbib.def</file>
<file>numeric.bbx</file>
<file>standard.bbx</file>
<file>numeric.cbx</file>
<file>biblatex.cfg</file>
<file>english.lbx</file>
</requires>
</internal>
<external package="biblatex" priority="5" active="1">
<generic>biber</generic>
<cmdline>
<binary>biber</binary>
<infile>testdoc1</infile>
</cmdline>
<input>
<file>testdoc1.bcf</file>
</input>
<output>
<file>testdoc1.bbl</file>
</output>
<provides type="dynamic">
<file>testdoc1.bbl</file>
</provides>
<requires type="dynamic">
<file>testdoc1.bcf</file>
</requires>
<requires type="editable">
<file>testdoc1.bib</file>
</requires>
</external>
</requests>
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