// Treerack syntax (self) // whitespace handling: wschar:alias = [ \t\n\b\f\r\v]; wsc:ws = wschar | comment; ws-no-nl:alias:nows = [ \t\b\f\r\v]; // whitespace without newline // comments: block-comment:alias:nows = "/*" ("*" [^/] | [^*])* "*/"; line-comment:alias:nows = "//" [^\n]*; comment-segment:alias:nows = line-comment | block-comment; comment:nows = comment-segment (ws-no-nl* "\n"? ws-no-nl* comment-segment)*; // characters: any-char = "."; // equivalent to [^] class-not = "^"; class-char:nows = [^\\\[\]\^\-] | "\\" .; // caution: newline is accepted char-range:nows = class-char "-" class-char; // foo char-class:nows = "[" class-not? (class-char | char-range)* "]"; // strings (char sequence): sequence-char:nows = [^\\"] | "\\" .; // caution: newline is accepted char-sequence:nows = "\"" sequence-char* "\""; // terminal parsers cannot be composed of other parsers: terminal:alias = any-char | char-class | char-sequence; // symbols can reference other parser definitions, or recursively the containing parser: symbol:nows = [^\\ \n\t\b\f\r\v/.\[\]\"{}\^+*?|():=;]+; // grouping allows, for example, use choices as sequence items: group:alias = "(" expression ")"; expression:alias = terminal | symbol | group | sequence | choice; // sequences with ranges: number:alias:nows = [0-9]+; count = number; count-quantifier = "{" count "}"; range-from = number; range-to = number; range-quantifier = "{" range-from? "," range-to? "}"; one-or-more = "+"; zero-or-more = "*"; zero-or-one = "?"; quantity:alias = count-quantifier | range-quantifier | one-or-more | zero-or-more | zero-or-one; item:nows = (terminal | symbol | group) quantity?; sequence = item+; // choices: option:alias = terminal | symbol | group | sequence; choice = option ("|" option)+; // flags control AST generation, whitespace handling and error propagation: alias = "alias"; ws = "ws"; nows = "nows"; kw = "kw"; nokw = "nokw"; failpass = "failpass"; root = "root"; flag:alias = alias | ws | nows | kw | nokw | failpass | root; // a syntax document consists of definitions: definition-name:alias:nows = symbol (":" flag)*; definition = definition-name "=" expression; definitions:alias = definition (";"+ definition)*; syntax:root = ";"* definitions? ";"*;