Commit dc1b5f68 authored by di68kap's avatar di68kap
Browse files

- sync commit

parent f7dca372
......@@ -73,81 +73,8 @@ def get_ebnf_preprocessor() -> PreprocessorFunc:
########################################################################
class EBNFGrammar(Grammar):
r"""Parser for an EBNF_variant source file, with this grammar:
# EBNF-Grammar in EBNF
@ comment = /#.*(?:\n|$)/ # comments start with '#' and eat all chars up to and including '\n'
@ whitespace = /\s*/ # whitespace includes linefeed
@ literalws = right # trailing whitespace of literals will be ignored tacitly
syntax = [~//] { definition | directive } §EOF
definition = symbol §"=" §expression
directive = "@" §symbol §"=" §( regexp | literal | list_ )
expression = term { "|" term }
term = { factor }+
factor = [flowmarker] [retrieveop] symbol !"=" # negative lookahead to be sure it's not a definition
| [flowmarker] literal
| [flowmarker] regexp
| [flowmarker] group
| [flowmarker] oneormore
| repetition
| option
flowmarker = "!" | "&" | "§" # '!' negative lookahead, '&' positive lookahead, '§' required
| "-!" | "-&" # '-' negative lookbehind, '-&' positive lookbehind
retrieveop = "::" | ":" # '::' pop, ':' retrieve
group = "(" expression §")"
oneormore = "{" expression "}+"
repetition = "{" expression §"}"
option = "[" expression §"]"
symbol = /(?!\d)\w+/~ # e.g. expression, factor, parameter_list
literal = /"(?:[^"]|\\")*?"/~ # e.g. "(", '+', 'while'
| /'(?:[^']|\\')*?'/~ # whitespace following literals will be ignored tacitly.
regexp = /~?\/(?:\\\/|[^\/])*?\/~?/~ # e.g. /\w+/, ~/#.*(?:\n|$)/~
# '~' is a whitespace-marker, if present leading or trailing
# whitespace of a regular expression will be ignored tacitly.
list_ = /\w+/~ { "," /\w+/~ } # comma separated list of symbols, e.g. BEGIN_LIST, END_LIST,
# BEGIN_QUOTE, END_QUOTE ; see CommonMark/markdown.py for an exmaple
EOF = !/./
"""
expression = Forward()
source_hash__ = "4735db10f0b79d44209d1de0184b2ca0"
parser_initialization__ = "upon instantiation"
COMMENT__ = r'#.*(?:\n|$)'
WHITESPACE__ = r'\s*'
WSP__ = mixin_comment(whitespace=WHITESPACE__, comment=COMMENT__)
wspL__ = ''
wspR__ = WSP__
EOF = NegativeLookahead(RegExp('.'))
list_ = Series(RE('\\w+'), ZeroOrMore(Series(Token(","), RE('\\w+'))))
regexp = RE('~?/(?:\\\\/|[^/])*?/~?')
literal = Alternative(RE('"(?:[^"]|\\\\")*?"'), RE("'(?:[^']|\\\\')*?'"))
symbol = RE('(?!\\d)\\w+')
option = Series(Token("["), expression, Required(Token("]")))
repetition = Series(Token("{"), expression, Required(Token("}")))
oneormore = Series(Token("{"), expression, Token("}+"))
group = Series(Token("("), expression, Required(Token(")")))
retrieveop = Alternative(Token("::"), Token(":"))
flowmarker = Alternative(Token("!"), Token("&"), Token("§"), Token("-!"), Token("-&"))
factor = Alternative(Series(Option(flowmarker), Option(retrieveop), symbol, NegativeLookahead(Token("="))),
Series(Option(flowmarker), literal), Series(Option(flowmarker), regexp),
Series(Option(flowmarker), group), Series(Option(flowmarker), oneormore), repetition, option)
term = OneOrMore(factor)
expression.set(Series(term, ZeroOrMore(Series(Token("|"), term))))
directive = Series(Token("@"), Required(symbol), Required(Token("=")),
Required(Alternative(regexp, literal, list_)))
definition = Series(symbol, Required(Token("=")), Required(expression))
syntax = Series(Option(RE('', wR='', wL=WSP__)), ZeroOrMore(Alternative(definition, directive)), Required(EOF))
root__ = syntax
# class EBNFGrammar(Grammar):
# r"""Parser for an EBNF source file, with this grammar:
# r"""Parser for an EBNF_variant source file, with this grammar:
#
# # EBNF-Grammar in EBNF
#
......@@ -156,11 +83,11 @@ class EBNFGrammar(Grammar):
# @ literalws = right # trailing whitespace of literals will be ignored tacitly
#
# syntax = [~//] { definition | directive } §EOF
# definition = symbol §"=" expression
# directive = "@" §symbol "=" ( regexp | literal | list_ )
# definition = symbol §"=" §expression
# directive = "@" §symbol §"=" §( regexp | literal | list_ )
#
# expression = term { "|" term }
# term = { ["§"] factor }+ # "§" means all following factors mandatory
# term = { factor }+
# factor = [flowmarker] [retrieveop] symbol !"=" # negative lookahead to be sure it's not a definition
# | [flowmarker] literal
# | [flowmarker] regexp
......@@ -169,7 +96,7 @@ class EBNFGrammar(Grammar):
# | repetition
# | option
#
# flowmarker = "!" | "&" # '!' negative lookahead, '&' positive lookahead
# flowmarker = "!" | "&" | "§" # '!' negative lookahead, '&' positive lookahead, '§' required
# | "-!" | "-&" # '-' negative lookbehind, '-&' positive lookbehind
# retrieveop = "::" | ":" # '::' pop, ':' retrieve
#
......@@ -189,7 +116,7 @@ class EBNFGrammar(Grammar):
# EOF = !/./
# """
# expression = Forward()
# source_hash__ = "a131abc5259738631000cda90d2fc65b"
# source_hash__ = "4735db10f0b79d44209d1de0184b2ca0"
# parser_initialization__ = "upon instantiation"
# COMMENT__ = r'#.*(?:\n|$)'
# WHITESPACE__ = r'\s*'
......@@ -197,34 +124,107 @@ class EBNFGrammar(Grammar):
# wspL__ = ''
# wspR__ = WSP__
# EOF = NegativeLookahead(RegExp('.'))
# list_ = Series(RE('\\w+'), ZeroOrMore(Series(Token(","), RE('\\w+'), mandatory=1000)),
# mandatory=1000)
# list_ = Series(RE('\\w+'), ZeroOrMore(Series(Token(","), RE('\\w+'))))
# regexp = RE('~?/(?:\\\\/|[^/])*?/~?')
# literal = Alternative(RE('"(?:[^"]|\\\\")*?"'), RE("'(?:[^']|\\\\')*?'"))
# symbol = RE('(?!\\d)\\w+')
# option = Series(Token("["), expression, Token("]"), mandatory=2)
# repetition = Series(Token("{"), expression, Token("}"), mandatory=2)
# oneormore = Series(Token("{"), expression, Token("}+"), mandatory=1000)
# group = Series(Token("("), expression, Token(")"), mandatory=2)
# option = Series(Token("["), expression, Required(Token("]")))
# repetition = Series(Token("{"), expression, Required(Token("}")))
# oneormore = Series(Token("{"), expression, Token("}+"))
# group = Series(Token("("), expression, Required(Token(")")))
# retrieveop = Alternative(Token("::"), Token(":"))
# flowmarker = Alternative(Token("!"), Token("&"), Token("-!"), Token("-&"))
# factor = Alternative(
# Series(Option(flowmarker), Option(retrieveop), symbol, NegativeLookahead(Token("=")),
# mandatory=1000), Series(Option(flowmarker), literal, mandatory=1000),
# Series(Option(flowmarker), regexp, mandatory=1000),
# Series(Option(flowmarker), group, mandatory=1000),
# Series(Option(flowmarker), oneormore, mandatory=1000), repetition, option)
# term = OneOrMore(Series(Option(Token("§")), factor, mandatory=1000))
# expression.set(
# Series(term, ZeroOrMore(Series(Token("|"), term, mandatory=1000)), mandatory=1000))
# directive = Series(Token("@"), symbol, Token("="), Alternative(regexp, literal, list_),
# mandatory=1)
# definition = Series(symbol, Token("="), expression, mandatory=1)
# syntax = Series(Option(RE('', wR='', wL=WSP__)), ZeroOrMore(Alternative(definition, directive)),
# EOF, mandatory=2)
# flowmarker = Alternative(Token("!"), Token("&"), Token("§"), Token("-!"), Token("-&"))
# factor = Alternative(Series(Option(flowmarker), Option(retrieveop), symbol, NegativeLookahead(Token("="))),
# Series(Option(flowmarker), literal), Series(Option(flowmarker), regexp),
# Series(Option(flowmarker), group), Series(Option(flowmarker), oneormore), repetition, option)
# term = OneOrMore(factor)
# expression.set(Series(term, ZeroOrMore(Series(Token("|"), term))))
# directive = Series(Token("@"), Required(symbol), Required(Token("=")),
# Required(Alternative(regexp, literal, list_)))
# definition = Series(symbol, Required(Token("=")), Required(expression))
# syntax = Series(Option(RE('', wR='', wL=WSP__)), ZeroOrMore(Alternative(definition, directive)), Required(EOF))
# root__ = syntax
class EBNFGrammar(Grammar):
r"""Parser for an EBNF source file, with this grammar:
# EBNF-Grammar in EBNF
@ comment = /#.*(?:\n|$)/ # comments start with '#' and eat all chars up to and including '\n'
@ whitespace = /\s*/ # whitespace includes linefeed
@ literalws = right # trailing whitespace of literals will be ignored tacitly
syntax = [~//] { definition | directive } §EOF
definition = symbol §"=" expression
directive = "@" §symbol "=" ( regexp | literal | list_ )
expression = term { "|" term }
term = { ["§"] factor }+ # "§" means all following factors mandatory
factor = [flowmarker] [retrieveop] symbol !"=" # negative lookahead to be sure it's not a definition
| [flowmarker] literal
| [flowmarker] regexp
| [flowmarker] group
| [flowmarker] oneormore
| repetition
| option
flowmarker = "!" | "&" # '!' negative lookahead, '&' positive lookahead
| "-!" | "-&" # '-' negative lookbehind, '-&' positive lookbehind
retrieveop = "::" | ":" # '::' pop, ':' retrieve
group = "(" expression §")"
oneormore = "{" expression "}+"
repetition = "{" expression §"}"
option = "[" expression §"]"
symbol = /(?!\d)\w+/~ # e.g. expression, factor, parameter_list
literal = /"(?:[^"]|\\")*?"/~ # e.g. "(", '+', 'while'
| /'(?:[^']|\\')*?'/~ # whitespace following literals will be ignored tacitly.
regexp = /~?\/(?:\\\/|[^\/])*?\/~?/~ # e.g. /\w+/, ~/#.*(?:\n|$)/~
# '~' is a whitespace-marker, if present leading or trailing
# whitespace of a regular expression will be ignored tacitly.
list_ = /\w+/~ { "," /\w+/~ } # comma separated list of symbols, e.g. BEGIN_LIST, END_LIST,
# BEGIN_QUOTE, END_QUOTE ; see CommonMark/markdown.py for an exmaple
EOF = !/./
"""
expression = Forward()
source_hash__ = "a131abc5259738631000cda90d2fc65b"
parser_initialization__ = "upon instantiation"
COMMENT__ = r'#.*(?:\n|$)'
WHITESPACE__ = r'\s*'
WSP__ = mixin_comment(whitespace=WHITESPACE__, comment=COMMENT__)
wspL__ = ''
wspR__ = WSP__
EOF = NegativeLookahead(RegExp('.'))
list_ = Series(RE('\\w+'), ZeroOrMore(Series(Token(","), RE('\\w+'), mandatory=1000)),
mandatory=1000)
regexp = RE('~?/(?:\\\\/|[^/])*?/~?')
literal = Alternative(RE('"(?:[^"]|\\\\")*?"'), RE("'(?:[^']|\\\\')*?'"))
symbol = RE('(?!\\d)\\w+')
option = Series(Token("["), expression, Token("]"), mandatory=2)
repetition = Series(Token("{"), expression, Token("}"), mandatory=2)
oneormore = Series(Token("{"), expression, Token("}+"), mandatory=1000)
group = Series(Token("("), expression, Token(")"), mandatory=2)
retrieveop = Alternative(Token("::"), Token(":"))
flowmarker = Alternative(Token("!"), Token("&"), Token("-!"), Token("-&"))
factor = Alternative(
Series(Option(flowmarker), Option(retrieveop), symbol, NegativeLookahead(Token("=")),
mandatory=1000), Series(Option(flowmarker), literal, mandatory=1000),
Series(Option(flowmarker), regexp, mandatory=1000),
Series(Option(flowmarker), group, mandatory=1000),
Series(Option(flowmarker), oneormore, mandatory=1000), repetition, option)
term = OneOrMore(Series(Option(Token("§")), factor, mandatory=1000))
expression.set(
Series(term, ZeroOrMore(Series(Token("|"), term, mandatory=1000)), mandatory=1000))
directive = Series(Token("@"), symbol, Token("="), Alternative(regexp, literal, list_),
mandatory=1)
definition = Series(symbol, Token("="), expression, mandatory=1)
syntax = Series(Option(RE('', wR='', wL=WSP__)), ZeroOrMore(Alternative(definition, directive)),
EOF, mandatory=2)
root__ = syntax
def grammar_changed(grammar_class, grammar_source: str) -> bool:
"""Returns ``True`` if ``grammar_class`` does not reflect the latest
changes of ``grammar_source``
......@@ -804,28 +804,31 @@ class EBNFCompiler(Compiler):
def on_term(self, node) -> str:
# mandatory_marker = []
# filtered_children = []
# i = 0
# for nd in node.children:
# if nd.parser.ptype == TOKEN_PTYPE and str(nd) == "§":
# mandatory_marker.append(i)
# if i == 0:
# nd.add_error('First item of a series should not be mandatory.',
# Error.WARNING)
# elif len(mandatory_marker) > 1:
# nd.add_error('One mandatory marker (§) sufficient to declare the '
# 'rest of the series as mandatory.', Error.WARNING)
# else:
# filtered_children.append(nd)
# i += 1
# saved_result = node.result
# node.result = tuple(filtered_children)
# mandatory_marker.append(Series.NOPE)
# compiled = self.non_terminal(node, 'Series', ['mandatory=%i' % mandatory_marker[0]])
# node.result = saved_result
# return compiled
return self.non_terminal(node, 'Series')
# Basically, the following code does only this:
# return self.non_terminal(node, 'Series')
# What makes it (look) more complicated is the handling of the
# mandatory §-operator
mandatory_marker = []
filtered_children = []
i = 0
for nd in node.children:
if nd.parser.ptype == TOKEN_PTYPE and str(nd) == "§":
mandatory_marker.append(i)
if i == 0:
nd.add_error('First item of a series should not be mandatory.',
Error.WARNING)
elif len(mandatory_marker) > 1:
nd.add_error('One mandatory marker (§) sufficient to declare the '
'rest of the series as mandatory.', Error.WARNING)
else:
filtered_children.append(nd)
i += 1
saved_result = node.result
node.result = tuple(filtered_children)
custom_args = ['mandatory=%i' % mandatory_marker[0]] if mandatory_marker else []
compiled = self.non_terminal(node, 'Series', custom_args)
node.result = saved_result
return compiled
def on_factor(self, node: Node) -> str:
......
......@@ -1420,6 +1420,7 @@ class Series(NaryOperator):
if pos < self.mandatory:
return None, text
else:
# Provide useful error messages
m = text.search(Series.RX_ARGUMENT)
i = max(1, text.index(m.regs[1][0])) if m else 1
node = Node(self, text[:i])
......@@ -1554,7 +1555,8 @@ class FlowOperator(UnaryOperator):
class Required(FlowOperator):
# Add constructor that checks for logical errors, like `Required(Option(...))` constructs ?
"""OBSOLETE. Use mandatory-parameter of Series-parser instead!
"""
RX_ARGUMENT = re.compile(r'\s(\S)')
def __call__(self, text: StringView) -> Tuple[Node, StringView]:
......
......@@ -238,15 +238,12 @@ class LaTeXGrammar(Grammar):
EOF = RegExp('(?!.)')
BACKSLASH = RegExp('[\\\\]')
LB = RegExp('\\s*?\\n|$')
NEW_LINE = Series(RegExp('[ \\t]*'), Option(RegExp(COMMENT__)), RegExp('\\n'), mandatory=1000)
NEW_LINE = Series(RegExp('[ \\t]*'), Option(RegExp(COMMENT__)), RegExp('\\n'))
GAP = RE('[ \\t]*(?:\\n[ \\t]*)+\\n')
WSPC = OneOrMore(Alternative(RegExp(COMMENT__), RegExp('\\s+')))
PARSEP = Series(ZeroOrMore(Series(RegExp(WHITESPACE__), RegExp(COMMENT__), mandatory=1000)),
GAP, Option(WSPC), mandatory=1000)
LFF = Series(NEW_LINE, Option(WSPC), mandatory=1000)
LF = Series(NEW_LINE,
ZeroOrMore(Series(RegExp(COMMENT__), RegExp(WHITESPACE__), mandatory=1000)),
mandatory=1000)
PARSEP = Series(ZeroOrMore(Series(RegExp(WHITESPACE__), RegExp(COMMENT__))), GAP, Option(WSPC))
LFF = Series(NEW_LINE, Option(WSPC))
LF = Series(NEW_LINE, ZeroOrMore(Series(RegExp(COMMENT__), RegExp(WHITESPACE__))))
TEXTCHUNK = RegExp('[^\\\\%$&\\{\\}\\[\\]\\s\\n]+')
INTEGER = RE('\\d+')
NAME = Capture(RE('\\w+'))
......@@ -257,33 +254,19 @@ class LaTeXGrammar(Grammar):
TXTCOMMAND = RegExp('\\\\text\\w+')
CMDNAME = RE('\\\\(?:(?!_)\\w)+')
structural = Alternative(Token("subsection"), Token("section"), Token("chapter"), Token("subsubsection"), Token("paragraph"), Token("subparagraph"), Token("item"))
blockcmd = Series(BACKSLASH, Alternative(Series(Alternative(Token("begin{"), Token("end{")),
Alternative(Token("enumerate"),
Token("itemize"), Token("figure"),
Token("quote"), Token("quotation"),
Token("tabular")), Token("}"),
mandatory=1000), structural,
begin_generic_block, end_generic_block),
mandatory=1000)
no_command = Alternative(Token("\\begin{"), Token("\\end"),
Series(BACKSLASH, structural, mandatory=1000))
text = Series(TEXTCHUNK, ZeroOrMore(Series(RE(''), TEXTCHUNK, mandatory=1000)), mandatory=1000)
block = Series(RegExp('{'), RE(''), ZeroOrMore(
Series(NegativeLookahead(blockcmd), text_element, RE(''), mandatory=1000)), RegExp('}'),
mandatory=3)
cfg_text = ZeroOrMore(
Alternative(Series(Option(RE('')), text, mandatory=1000), CMDNAME, SPECIAL))
blockcmd = Series(BACKSLASH, Alternative(Series(Alternative(Token("begin{"), Token("end{")), Alternative(Token("enumerate"), Token("itemize"), Token("figure"), Token("quote"), Token("quotation"), Token("tabular")), Token("}")), structural, begin_generic_block, end_generic_block))
no_command = Alternative(Token("\\begin{"), Token("\\end"), Series(BACKSLASH, structural))
text = Series(TEXTCHUNK, ZeroOrMore(Series(RE(''), TEXTCHUNK)))
block = Series(RegExp('{'), RE(''), ZeroOrMore(Series(NegativeLookahead(blockcmd), text_element, RE(''))), RegExp('}'), mandatory=3)
cfg_text = ZeroOrMore(Alternative(Series(Option(RE('')), text), CMDNAME, SPECIAL))
config = Series(Token("["), cfg_text, Token("]"), mandatory=2)
cline = Series(Token("\\cline{"), INTEGER, Token("-"), INTEGER, Token("}"), mandatory=1000)
cline = Series(Token("\\cline{"), INTEGER, Token("-"), INTEGER, Token("}"))
hline = Token("\\hline")
multicolumn = Series(Token("\\multicolumn"), Token("{"), INTEGER, Token("}"), tabular_config,
block_of_paragraphs, mandatory=1000)
caption = Series(Token("\\caption"), block, mandatory=1000)
includegraphics = Series(Token("\\includegraphics"), Option(config), block, mandatory=1000)
footnote = Series(Token("\\footnote"), block_of_paragraphs, mandatory=1000)
generic_command = Series(NegativeLookahead(no_command), CMDNAME, Option(
Series(Option(Series(RE(''), config, mandatory=1000)), RE(''), block, mandatory=1000)),
mandatory=1000)
multicolumn = Series(Token("\\multicolumn"), Token("{"), INTEGER, Token("}"), tabular_config, block_of_paragraphs)
caption = Series(Token("\\caption"), block)
includegraphics = Series(Token("\\includegraphics"), Option(config), block)
footnote = Series(Token("\\footnote"), block_of_paragraphs)
generic_command = Series(NegativeLookahead(no_command), CMDNAME, Option(Series(Option(Series(RE(''), config)), RE(''), block)))
text_command = Alternative(TXTCOMMAND, ESCAPED, BRACKETS)
known_command = Alternative(footnote, includegraphics, caption, multicolumn, hline, cline)
command = Alternative(known_command, text_command, generic_command)
......@@ -291,68 +274,48 @@ class LaTeXGrammar(Grammar):
end_environment = Series(RegExp('\\\\end{'), Pop(NAME), RegExp('}'), mandatory=1)
begin_environment = Series(RegExp('\\\\begin{'), NAME, RegExp('}'), mandatory=1)
end_inline_env = Synonym(end_environment)
begin_inline_env = Alternative(
Series(NegativeLookbehind(LB), begin_environment, mandatory=1000),
Series(begin_environment, NegativeLookahead(LFF), mandatory=1000))
begin_inline_env = Alternative(Series(NegativeLookbehind(LB), begin_environment), Series(begin_environment, NegativeLookahead(LFF)))
generic_inline_env = Series(begin_inline_env, RE(''), paragraph, end_inline_env, mandatory=3)
known_inline_env = Synonym(inline_math)
inline_environment = Alternative(known_inline_env, generic_inline_env)
line_element = Alternative(text, block, inline_environment, command)
text_element.set(Alternative(line_element, LINEFEED))
paragraph.set(
OneOrMore(Series(NegativeLookahead(blockcmd), text_element, RE(''), mandatory=1000)))
sequence = OneOrMore(
Series(Alternative(paragraph, block_environment), Option(PARSEP), mandatory=1000))
paragraph.set(OneOrMore(Series(NegativeLookahead(blockcmd), text_element, RE(''))))
sequence = OneOrMore(Series(Alternative(paragraph, block_environment), Option(PARSEP)))
block_of_paragraphs.set(Series(Token("{"), Option(sequence), Token("}"), mandatory=2))
tabular_config.set(Series(Token("{"), RE('[lcr|]+'), Token("}"), mandatory=2))
tabular_cell = ZeroOrMore(Series(line_element, RE(''), mandatory=1000))
tabular_row = Series(Alternative(multicolumn, tabular_cell), ZeroOrMore(
Series(Token("&"), Alternative(multicolumn, tabular_cell), mandatory=1000)), Token("\\\\"),
Alternative(hline, ZeroOrMore(cline)), mandatory=1000)
tabular = Series(Token("\\begin{tabular}"), tabular_config, ZeroOrMore(tabular_row),
Token("\\end{tabular}"), mandatory=3)
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)))
tabular = Series(Token("\\begin{tabular}"), tabular_config, ZeroOrMore(tabular_row), Token("\\end{tabular}"), mandatory=3)
verbatim = Series(Token("\\begin{verbatim}"), sequence, Token("\\end{verbatim}"), mandatory=2)
quotation = Alternative(
Series(Token("\\begin{quotation}"), sequence, Token("\\end{quotation}"), mandatory=2),
Series(Token("\\begin{quote}"), sequence, Token("\\end{quote}"), mandatory=2))
quotation = Alternative(Series(Token("\\begin{quotation}"), sequence, Token("\\end{quotation}"), mandatory=2), Series(Token("\\begin{quote}"), sequence, Token("\\end{quote}"), mandatory=2))
figure = Series(Token("\\begin{figure}"), sequence, Token("\\end{figure}"), mandatory=2)
item = Series(Token("\\item"), Option(WSPC), sequence, mandatory=1000)
enumerate = Series(Token("\\begin{enumerate}"), Option(WSPC), ZeroOrMore(item),
Token("\\end{enumerate}"), mandatory=3)
itemize = Series(Token("\\begin{itemize}"), Option(WSPC), ZeroOrMore(item),
Token("\\end{itemize}"), mandatory=3)
end_generic_block.set(Series(Lookbehind(LB), end_environment, LFF, mandatory=1000))
begin_generic_block.set(Series(Lookbehind(LB), begin_environment, LFF, mandatory=1000))
item = Series(Token("\\item"), Option(WSPC), sequence)
enumerate = Series(Token("\\begin{enumerate}"), Option(WSPC), ZeroOrMore(item), Token("\\end{enumerate}"), mandatory=3)
itemize = Series(Token("\\begin{itemize}"), Option(WSPC), ZeroOrMore(item), Token("\\end{itemize}"), mandatory=3)
end_generic_block.set(Series(Lookbehind(LB), end_environment, LFF))
begin_generic_block.set(Series(Lookbehind(LB), begin_environment, LFF))
generic_block = Series(begin_generic_block, sequence, end_generic_block, mandatory=2)
known_environment = Alternative(itemize, enumerate, figure, tabular, quotation, verbatim)
block_environment.set(Alternative(known_environment, generic_block))
Index = Series(Token("\\printindex"), Option(WSPC), mandatory=1000)
Bibliography = Series(Token("\\bibliography"), block, Option(WSPC), mandatory=1000)
SubParagraph = Series(Token("\\subparagraph"), block, Option(WSPC), Option(sequence),
mandatory=1000)
SubParagraphs = OneOrMore(Series(SubParagraph, Option(WSPC), mandatory=1000))
Paragraph = Series(Token("\\paragraph"), block, Option(WSPC),
ZeroOrMore(Alternative(sequence, SubParagraphs)), mandatory=1000)
Paragraphs = OneOrMore(Series(Paragraph, Option(WSPC), mandatory=1000))
SubSubSection = Series(Token("\\subsubsection"), block, Option(WSPC),
ZeroOrMore(Alternative(sequence, Paragraphs)), mandatory=1000)
SubSubSections = OneOrMore(Series(SubSubSection, Option(WSPC), mandatory=1000))
SubSection = Series(Token("\\subsection"), block, Option(WSPC),
ZeroOrMore(Alternative(sequence, SubSubSections)), mandatory=1000)
SubSections = OneOrMore(Series(SubSection, Option(WSPC), mandatory=1000))
Section = Series(Token("\\section"), block, Option(WSPC),
ZeroOrMore(Alternative(sequence, SubSections)), mandatory=1000)
Sections = OneOrMore(Series(Section, Option(WSPC), mandatory=1000))
Chapter = Series(Token("\\chapter"), block, Option(WSPC),
ZeroOrMore(Alternative(sequence, Sections)), mandatory=1000)
Chapters = OneOrMore(Series(Chapter, Option(WSPC), mandatory=1000))
Index = Series(Token("\\printindex"), Option(WSPC))
Bibliography = Series(Token("\\bibliography"), block, Option(WSPC))
SubParagraph = Series(Token("\\subparagraph"), block, Option(WSPC), Option(sequence))
SubParagraphs = OneOrMore(Series(SubParagraph, Option(WSPC)))
Paragraph = Series(Token("\\paragraph"), block, Option(WSPC), ZeroOrMore(Alternative(sequence, SubParagraphs)))
Paragraphs = OneOrMore(Series(Paragraph, Option(WSPC)))
SubSubSection = Series(Token("\\subsubsection"), block, Option(WSPC), ZeroOrMore(Alternative(sequence, Paragraphs)))
SubSubSections = OneOrMore(Series(SubSubSection, Option(WSPC)))
SubSection = Series(Token("\\subsection"), block, Option(WSPC), ZeroOrMore(Alternative(sequence, SubSubSections)))
SubSections = OneOrMore(Series(SubSection, Option(WSPC)))
Section = Series(Token("\\section"), block, Option(WSPC), ZeroOrMore(Alternative(sequence, SubSections)))
Sections = OneOrMore(Series(Section, Option(WSPC)))
Chapter = Series(Token("\\chapter"), block, Option(WSPC), ZeroOrMore(Alternative(sequence, Sections)))
Chapters = OneOrMore(Series(Chapter, Option(WSPC)))
frontpages = Synonym(sequence)
document = Series(Option(WSPC), Token("\\begin{document}"), Option(WSPC), frontpages,
Option(WSPC), Alternative(Chapters, Sections), Option(WSPC),
Option(Bibliography), Option(Index), Option(WSPC), Token("\\end{document}"),
Option(WSPC), EOF, mandatory=12)
preamble = OneOrMore(Series(Option(WSPC), command, mandatory=1000))
latexdoc = Series(preamble, document, mandatory=1000)
document = Series(Option(WSPC), Token("\\begin{document}"), Option(WSPC), frontpages, Option(WSPC), Alternative(Chapters, Sections), Option(WSPC), Option(Bibliography), Option(Index), Option(WSPC), Token("\\end{document}"), Option(WSPC), EOF, mandatory=12)
preamble = OneOrMore(Series(Option(WSPC), command))
latexdoc = Series(preamble, document)
root__ = latexdoc
def get_grammar() -> LaTeXGrammar:
......
......@@ -30,7 +30,7 @@ from DHParser import toolkit
# print(dir(dsl))
with toolkit.logging(False):
if not dsl.recompile_grammar('LaTeX.ebnf', force=False): # recompiles Grammar only if it has
if not dsl.recompile_grammar('LaTeX.ebnf', force=True): # recompiles Grammar only if it has
# changed
print(
'\nErrors while recompiling "LaTeX.ebnf":\n--------------------------------------\n\n')
......
......@@ -130,7 +130,6 @@ class TestEBNFParser:
}
}
def setup(self):
self.EBNF = get_ebnf_grammar()
......
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