-- Morg description for Morgana morg Morgana start Morg node Morg := ( name : [ MorgName ], start_symbol : [ StartStatement ], _ : { Statement } ) squash MorgName := Keyword::Morg Identifier node StartStatement := Keyword::Start Identifier squash Statement := | Definition: Definition | Skip : Skip | Special : Special node Skip := Keyword::Skip Builtin node SumConstructor := ( name: Identifier Operator::TypeDefinition, constructor: Expression ) node SumDefinition := Delimiter::Pipe << Delimiter::Pipe , SumConstructor >> node ProdConstructor := ( field: Identifier Operator::TypeDefinition, type: Expression ) node ProdDefinition := Delimiter::LParen << Delimiter::Comma , ProdConstructor >> Delimiter::RParen node Special := ( key: Keyword::Special SpecialKeyword Operator::Definition, const: SpecialConstructor ) node SpecialConstructor := | Sum : SumDefinition | Prod : ProdDefinition | Alias : Expression node SpecialKeyword := | Comment: "Comment" | Whitespace: "Whitespace" | Keyword: "Keyword" | Operator: "Operator" | Delimiter: "Delimiter" | Builtin: "Builtin" | Identifier: "Identifier" node Definition := | Node : Keyword::Node NodeDefinition | Squash : Keyword::Squash SquashDefinition node NodeDefinition := ( name: Identifier Operator::Definition, constructor: NodeConstructor ) node NodeConstructor := | Sum : SumDefinition | Prod : ProdDefinition | Alias : Expression node SquashDefinition := ( name: Identifier Operator::Definition, constructor: SquashConstructor ) node SquashConstructor := | Sum : SumDefinition | Alias : Expression node Expression := ( factors: < Factor > ) node Factor := | NonTerminal : NonTerminal | Builtin : Builtin | Option : Option | Repetition : Repetition | RepetitionSep : RepetitionSep | Once : Once | OnceSep : OnceSep node Option := Delimiter::LBracket Expression Delimiter::RBracket node Repetition := Delimiter::LBrace Expression Delimiter::RBrace node RepetitionSep := Delimiter::LDBrace Expression Delimiter::Comma Expression Delimiter::RDBrace node Once := Delimiter::LAngle Expression Delimiter::RAngle node OnceSep := Delimiter::LDAngle Expression Delimiter::Comma Expression Delimiter::RDAngle node NonTerminal := << "::", Identifier >> special Builtin := | Char : "'" CharContent "'" | String : '"' { StringContent } '"' | Regex : '/' { RegexContent } '/' node RegexContent := | Character : /[^\/]/ | EscapedFSlash: "\\/" node CharContent := | Escape : '\\' Escape | Character: /[^']/ node StringContent := | Escape : '\\' Escape | Character: /[^"]/ node Escape := | Slash : '\\' | FSlash : '/' | NewLine : 'n' | Tab : 't' | CarriageReturn : 'r' | Nil : '0' | Quote: "'" | DQuote: '"' special Comment := "--" /[^\n]*/ "\n" special Keyword := | Node : "node" | Squash : "squash" | Special : "special" | Skip : "skip" | Morg : "morg" | Start : "start" special Operator := | Definition: ":=" | TypeDefinition: ":" special Delimiter := | Comma : "," | Pipe : "|" | LParen : "(" | RParen : ")" | LBracket : "[" | RBracket : "]" | LBrace : "{" | RBrace : "}" | LDBrace : "{{" | RDBrace : "}}" | LAngle : "<" | RAngle : ">" | LDAngle : "<<" | RDAngle : ">>" special Identifier := /[a-zA-Z_][a-zA-Z0-9_]*/ skip /[\s]/