def makeGrammarExpressionFragment( finalGrammar: Grammar = [GrammarItem(r";", FragmentNewElement)]) -> Grammar: """ Generate a grammar for an expression, it accepts the following format: type[(arg1, arg2, ...)] [contract]; """ class ArgumentStart(FragmentNestedStart): nestedName = "argument" grammarValue = [ GrammarItem(_regexprValue, Fragment, [ GrammarItem(r",", FragmentNewElement), GrammarItem(r"\)", FragmentParentElement) ]), GrammarItem(_regexprType, Fragment, [ GrammarItem(r",", FragmentNewElement), GrammarItem(r"\)", FragmentParentElement) ]) ] return makeGrammarType([ GrammarItem(r"\(", ArgumentStart, [ GrammarItem(_regexprName + r"\s*=", Fragment, grammarValue), GrammarItem(r"\)", FragmentParentElement) ] + grammarValue), makeGrammarContracts(), finalGrammar ])
def makeGrammarControlStop(fragment: typing.Type[Fragment], grammar: typing.Optional[typing.Union[Grammar, str]] = None) -> Grammar: return [ GrammarItem(r"(?=%})", Fragment, [GrammarItem(r"%}([ \t]*\n[ \t]*(?={[%#])|[ \t]*\n|[. \t]*$)?", fragment, grammar)]), GrammarItem(r"(?=-%})", Fragment, [GrammarItem(r"-%}\s*", fragment, grammar)]), ]
def makeNestedCategory(name: str) -> GrammarItem: class CategoryFragmentStart(FragmentNestedStart): nestedName = name return GrammarItem( name + r"(?=:)", FragmentParentElement, [GrammarItem(r":", CategoryFragmentStart, "nested")])
def makeGrammarUse() -> Grammar: """ Generate a grammar for use, it accepts the following format: use "path/to/file" """ return [ GrammarItem(r"use", {"category": "use"}, [GrammarItem(_regexprString, FragmentNewElement)]) ]
def makeGrammarControlIf() -> Grammar: """ Generate the grammar for the if block. It matches the following: if condition %} """ return makeGrammarControlStart(r"if", [ GrammarItem(None, {"category": "if"}, [GrammarItem(_regexprCondition, Fragment, makeGrammarControlStop(FragmentNestedStart, "root"))]) ])
def makeGrammarMethod() -> Grammar: """ Generate a grammar for methods, it accepts the following format: method name([inputs...]) [contract] [-> returntype [contract]]; """ class ArgumentStart(FragmentNestedStart): nestedName = "argument" return [ GrammarItem(r"method", {"category": "method"}, [ GrammarItem(_regexprName, Fragment, [ GrammarItem(r"\(", ArgumentStart, [ makeGrammarVariable([ GrammarItem(r",", FragmentNewElement), GrammarItem(r"\)", FragmentParentElement) ]), GrammarItem(r"\)", FragmentParentElement) ]), makeGrammarContracts(), GrammarItem(r"->", Fragment, [ makeGrammarType([ makeGrammarContracts(name="contract_return"), GrammarItem(r";", FragmentNewElement) ]) ]), GrammarItem(r";", FragmentNewElement) ]) ]) ]
def makeGrammarValue(fragment: typing.Dict[str, str], grammar: Grammar) -> Grammar: """ A value is either a name, a number or a string. """ return [ GrammarItem(_regexprNumber, dict(fragment, type="number"), grammar), GrammarItem(_regexprString, dict(fragment, type="string"), grammar), GrammarItem(_regexprBooleanTrue, dict(fragment, type="true"), grammar), GrammarItem(_regexprBooleanFalse, dict(fragment, type="false"), grammar), GrammarItem(makeRegexprName("value"), dict(fragment, type="name"), grammar), ]
def makeGrammarVariable( finalGrammar: Grammar = [GrammarItem(r";", FragmentNewElement)]) -> Grammar: """ Generate a grammar for Variables, it accepts the following format: name = type[(value)] [contract]; """ return [ GrammarItem(_regexprNameOrVarArgs + r"\s*=", {"category": "expression"}, makeGrammarExpressionFragment(finalGrammar)) ]
def makeGrammarExpression() -> Grammar: """ Generate a grammar for Variables, it accepts the following format: [name =] type[(value)] [contract]; """ finalGrammar: Grammar = [GrammarItem(r";", FragmentNewElement)] return makeGrammarVariable(finalGrammar) + [ GrammarItem(r"(?=" + _regexprBaseName + r")", {"category": "expression"}, makeGrammarExpressionFragment(finalGrammar)) ]
def makeGrammarControlEnd() -> Grammar: """ Generate the grammar for the end control block. """ class FragmentEndElement(FragmentNewElement): default = {"category": "end"} return [ GrammarItem( r"(?={%-?\s*end)", FragmentParentElement, makeGrammarControlStart(r"end", [GrammarItem(None, FragmentNewElement, makeGrammarControlStop(FragmentEndElement))])) ]
def makeGrammarContracts(name: str = "contract") -> Grammar: """ Generate a grammar for Contracts, it accepts the following format: [Type1[(value1, value2, ...)], Type2[(value1, value2, ...)] ...] Nested type elements are included under `contracts`. """ class ContractStart(FragmentNestedStart): nestedName = name class ValuesStart(FragmentNestedStart): nestedName = "values" return [ GrammarItem(r"\[", ContractStart, [ GrammarItem(_regexprType, Fragment, [ GrammarItem(r"\(", ValuesStart, [ GrammarItem(_regexprValue, Fragment, [ GrammarItem(r",", FragmentNewElement), GrammarItem(r"\)", FragmentParentElement), ]), ]), GrammarItem(r"\]", FragmentParentElement), GrammarItem(r"", FragmentNewElement), ]) ]), ]
def makeGrammarContent() -> Grammar: """ Generate a grammar for the raw content. """ class FragmentContent(FragmentNewElement): default = {"category": "content"} return [ # Note the order is important here. GrammarItem(_regexprContentStripRight, FragmentContent), GrammarItem(_regexprContentStripAuto, FragmentContent), GrammarItem(_regexprContent, FragmentContent), GrammarItem(_regexprContentEndOfFile, FragmentContent) ]
def makeGrammarComments() -> Grammar: """ Generate the grammar code comments. """ return makeGrammarCommentStart( [GrammarItem(_regexprComment, {"category": "comment"}, makeGrammarCommentStop(FragmentNewElement))])
def makeGrammarSubstitution() -> Grammar: """ Generate a grammar for substitution blocks. """ class PipeStart(FragmentNestedStart): nestedName = "pipe" return makeGrammarSubstitutionStart( makeGrammarSymbol({"category": "substitution"}, [ GrammarItem(r"\|", PipeStart, [ GrammarItem(makeRegexprName("name"), Fragment, [GrammarItem(r"\|", FragmentNewElement), GrammarItem(None, FragmentParentElement)]) ]) ] + makeGrammarSubstitutionStop(FragmentNewElement)) + makeGrammarSubstitutionStop(FragmentNewElement))
def makeGrammarNamespace() -> Grammar: """ Generate a grammar for namespace, it accepts the following format: namespace level1[.level2[.level3...]]; """ class NamespaceStart(FragmentNestedStart): default = {"category": "namespace"} nestedName = "name" return [ GrammarItem(r"namespace", NamespaceStart, [ GrammarItem(_regexprName, Fragment, [ GrammarItem(r"\.", FragmentNewElement), GrammarItem(r";", FragmentNestedStopNewElement) ]) ]) ]
def makeGrammarControlElseIf() -> Grammar: """ Generate the grammar for the else / elif block. It matches the following: else %} elif condition %} """ class ElseFragment(FragmentNestedStart): default = {"category": "else"} return [ GrammarItem( r"(?={%-?\s*(else|elif))", FragmentNestedStopNewElement, makeGrammarControlStart(r"elif", [GrammarItem(_regexprCondition, {"category": "else"}, makeGrammarControlStop(FragmentNestedStart, "root"))]) + makeGrammarControlStart(r"else", makeGrammarControlStop(ElseFragment, "root"))) ]
def makeGrammarSymbol(fragment: typing.Dict[str, str], grammar: Grammar) -> Grammar: """ Generate a grammar for a symbol. A symbol is a entity that must be resolved from substitution. """ class ArgumentStart(FragmentNestedStart): nestedName = "argument" return [ GrammarItem(makeRegexprName("name"), fragment, [ GrammarItem( r"\(", ArgumentStart, makeGrammarValue({}, [GrammarItem(r",", FragmentNewElement), GrammarItem(r"\)", FragmentParentElement, grammar)]) + [GrammarItem(r"\)", FragmentParentElement, grammar)]) ] + grammar) ]
def makeGrammarUsing() -> Grammar: """ Generate a grammar for using keyword, it accepts the following format: using name = Type [contract]; """ return [ GrammarItem(r"using", {"category": "using"}, [ GrammarItem(_regexprName, Fragment, [ GrammarItem( r"=", Fragment, makeGrammarType([ makeGrammarContracts(), GrammarItem(r";", FragmentNewElement) ])) ]) ]) ]
def makeGrammarControl() -> Grammar: """ Generate the grammar for all control blocks. """ return [ GrammarItem( r"(?={%)", Fragment, makeGrammarControlFor() + makeGrammarControlIf() + makeGrammarControlElseIf() + makeGrammarControlMacro() + makeGrammarControlInclude() + makeGrammarControlEnd()) ]
def makeGrammarControlMacro() -> Grammar: """ Generate the grammar for a macro block. It matches the following: macro name(arg1, arg2, ...) %} """ class ArgumentStart(FragmentNestedStart): nestedName = "argument" default = {"category": "macro"} return makeGrammarControlStart(r"macro", [ GrammarItem(_regexprIdentifier + r"\(", ArgumentStart, [ GrammarItem(makeRegexprName("name"), Fragment, [ GrammarItem(r",", FragmentNewElement), GrammarItem(r"\)", FragmentParentElement, makeGrammarControlStop(FragmentNestedStart, "root")) ]), GrammarItem(r"\)", FragmentParentElement, makeGrammarControlStop(FragmentNestedStart, "root")) ]) ])
def makeGrammarNested(nestedGrammar: Grammar, trivial: bool = False) -> Grammar: """ Generate a grammar for a nested entity, it accepst the following format: (interface|struct|component|composition) [name] [contracts] [: inheritance1, inheritance2, ...] { nestedGrammar } Nested type elements are included under `nested`. """ class InheritanceStart(FragmentNestedStart): nestedName = "inheritance" class NestedInterface(FragmentNestedStart): nestedName = "interface" def makeNestedCategory(name: str) -> GrammarItem: class CategoryFragmentStart(FragmentNestedStart): nestedName = name return GrammarItem( name + r"(?=:)", FragmentParentElement, [GrammarItem(r":", CategoryFragmentStart, "nested")]) grammarAfterName: Grammar = [ GrammarItem(r":", InheritanceStart, [ GrammarItem(_regexprSymbol, Fragment, [ GrammarItem(r",", FragmentNewElement), GrammarItem(r"(?={)", FragmentParentElement) ]) ]), GrammarItem( r"{", NestedInterface, nestedGrammar + [ makeNestedCategory("config"), makeNestedCategory("composition"), makeNestedCategory("interface"), GrammarItem(r"}", FragmentNestedStopNewElement), ], "nested"), ] + makeGrammarContracts() return [ GrammarItem(_regexprNestedTrivial if trivial else _regexprNested, {"category": "nested"}, [GrammarItem(_regexprName, Fragment, grammarAfterName)] + grammarAfterName) ]
def makeGrammarType(nextGrammar: Grammar) -> Grammar: """ Generate a grammar for Type, it accepts the following format: Type = [const] Type1[<Type, Type, ...>] Nested type elements are included under `template`. """ class TemplateStart(FragmentNestedStart): nestedName = "template" grammar: Grammar = [GrammarItem(r"const", {"const": ""})] followUpGrammar: Grammar = [ GrammarItem(r"<", TemplateStart, [grammar]), GrammarItem(r",", FragmentNewElement), GrammarItem(r">", FragmentParentElement), nextGrammar ] grammar.append(GrammarItem(_regexprValue, Fragment, followUpGrammar)) grammar.append(GrammarItem(_regexprType, Fragment, followUpGrammar)) return grammar
def makeGrammarControlFor() -> Grammar: """ Generate the grammar for the for loop control block. It matches the following: for value1 [, value2] in iterable %} """ grammarFromIn = [ GrammarItem(r"in", Fragment, [GrammarItem(makeRegexprName("iterable"), Fragment, makeGrammarControlStop(FragmentNestedStart, "root"))]) ] return makeGrammarControlStart(r"for", [ GrammarItem(None, {"category": "for"}, [ GrammarItem(makeRegexprName("value1"), Fragment, [GrammarItem(r",", Fragment, [GrammarItem(makeRegexprName("value2"), Fragment, grammarFromIn)])] + grammarFromIn) ]) ])
def makeGrammarEnum() -> Grammar: """ Generate a grammar for an enum, it accepts the following format: enum name { VALUE1 [,VALUE2 [,...]] } """ class EnumStart(FragmentNestedStart): nestedName = "values" return [ GrammarItem(r"enum", {"category": "enum"}, [ GrammarItem(_regexprName, Fragment, [ GrammarItem(r"{", EnumStart, [ GrammarItem(_regexprName, Fragment, [ GrammarItem(r",", FragmentNewElement), GrammarItem(r"}", FragmentNestedStopNewElement), ]) ]) ]) ]) ]
def makeGrammarUse() -> Grammar: """ Generate a grammar for use, it accepts the following format: use "path/to/file" """ return [ GrammarItem(r"use", {"category": "use"}, [GrammarItem(_regexprString, FragmentNewElement)]) ] # Comments allowed by the grammar _grammarComments = [ GrammarItem(r"/\*(?P<comment>([\s\S]*?))\*/", FragmentBlockComment), GrammarItem(r"//(?P<comment>[^\n]*)", FragmentComment) ] class Parser(ParserBase): def __init__(self, content: str) -> None: withinNested = makeGrammarUsing() + makeGrammarEnum( ) + makeGrammarExpression() + makeGrammarMethod() nested = withinNested + makeGrammarNested( withinNested + makeGrammarNested(withinNested + makeGrammarNested( withinNested + makeGrammarNested(withinNested + makeGrammarNested( withinNested, trivial=True), trivial=True),
def makeGrammarCommentStop(fragment: typing.Type[Fragment]) -> Grammar: return [ GrammarItem(r"(?=#})", Fragment, [GrammarItem(r"#}([ \t]*\n[ \t]*(?={[%#])|[ \t]*\n|[. \t]*$)?", fragment)]), GrammarItem(r"(?=-#})", Fragment, [GrammarItem(r"-#}\s*", fragment)]), ]
def makeGrammarSubstitutionStop(fragment: typing.Type[Fragment]) -> Grammar: return [ GrammarItem(r"(?=}})", Fragment, [GrammarItem(r"}}", fragment)]), GrammarItem(r"(?=-}})", Fragment, [GrammarItem(r"-}}\s*", fragment)]), ]
def makeGrammarCommentStart(grammar: Grammar) -> Grammar: return [ GrammarItem(r"(^[ \t]*)?{#-?", Fragment, grammar), ]
def makeGrammarControlStart(keyword: str, grammar: Grammar) -> Grammar: return [ GrammarItem(r"(^[ \t]*)?{%-?\s*" + keyword, Fragment, grammar), ]
def makeGrammarSubstitutionStart(grammar: Grammar) -> Grammar: return [GrammarItem(r"{{-?", Fragment, grammar)]