protected GroupParser(GroupParser other, ParserCloneArgs chain) : base(other, chain) { this.Line = chain.Clone(other.Line); this.Start = chain.Clone(other.Start); this.End = chain.Clone(other.End); }
public XmlGrammar() : base("xml") { EnableMatchEvents = false; var comment = new GroupParser("<!--", "-->"); var ws = Terminals.Repeat(Char.IsWhiteSpace, 1); var ows = Terminals.Repeat(Char.IsWhiteSpace, 0); var wsc = -(ws | comment); var name = Terminals.Repeat(new RepeatCharItem(Char.IsLetter, 1, 1), new RepeatCharItem(Char.IsLetterOrDigit, 0)); var namedName = Terminals.Repeat(new RepeatCharItem(Char.IsLetter, 1, 1), new RepeatCharItem(Char.IsLetterOrDigit, 0)).WithName("name"); var text = new UntilParser("<", 1).WithName("text"); var attributeValue = new StringParser { QuoteCharacters = new [] { '"' }, Name = "value" }; var attribute = (namedName & ows & "=" & ows & attributeValue); var attributes = (ws & (+attribute).SeparatedBy(ws).WithName("attributes")).Optional(); var content = new RepeatParser { Separator = wsc }; var startTag = "<" & namedName & attributes & ows; var endTag = "</" & name & ">"; var obj = (startTag & ("/>" | (">" & wsc & content & wsc & endTag))).WithName("object"); var cdata = ("<![CDATA[" & new UntilParser("]]>", 0, skip: true)).WithName("cdata"); content.Inner = obj | text | cdata; var declaration = "<?" & name & attributes & ows & "?>"; Inner = declaration & wsc & obj & wsc; }
protected GroupParser(GroupParser other, ParserCloneArgs chain) : base(other, chain) { this.line = chain.Clone(other.line); this.start = chain.Clone(other.start); this.end = chain.Clone(other.end); SetLine(); SetBlock(); SetInner(); }
public GoldGrammar() : base("gold") { var oldSeparator = Parser.DefaultSeparator; // Special Terminals var parameterCh = Terminals.Printable - Terminals.Set("\"'"); var nonterminalCh = Terminals.LetterOrDigit | Terminals.Set("_-. "); var terminalCh = Terminals.LetterOrDigit | Terminals.Set("_-."); var literalCh = Terminals.Printable - Terminals.Set('\''); var setLiteralCh = Terminals.Printable - Terminals.Set("[]'"); var setNameCh = Terminals.Printable - Terminals.Set("{}"); var parameterName = ('"' & (+parameterCh).WithName("value") & '"').Separate(); var nonterminal = ('<' & (+nonterminalCh).WithName("value") & '>').Separate(); var terminal = ((+terminalCh).WithName("terminal") | ('\'' & (-literalCh).WithName("literal") & '\'')).Separate(); var setLiteral = ('[' & +(setLiteralCh.WithName("ch") | '\'' & (-literalCh).WithName("ch") & '\'') & ']').WithName("setLiteral"); var setName = ('{' & (+setNameCh).WithName("value") & '}').WithName("setName"); // Line-Based Grammar Declarations var comments = new GroupParser("!*", "*!", "!"); var newline = Terminals.Eol; whitespace = -(Terminals.SingleLineWhiteSpace | comments); Parser.DefaultSeparator = whitespace; var nlOpt = -newline; var nl = +newline | Terminals.End; // Parameter Definition var parameterItem = parameterName | terminal | setLiteral | setName | nonterminal; var parameterItems = +parameterItem; var parameterBody = parameterItems & -(nlOpt & '|' & parameterItems); parameter = (parameterName.Named("name") & nlOpt & '=' & parameterBody.WithName("body") & nl).WithName("parameter"); // Set Definition var setItem = setLiteral | setName; var setExp = new AlternativeParser { Name = "setExp" }; setExp.Add((setExp & nlOpt & '+' & setItem).WithName("add"), (setExp & nlOpt & '-' & setItem).WithName("sub"), setItem); setDecl = (setName & nlOpt & '=' & setExp & nl).WithName("setDecl"); // Terminal Definition var regExp2 = new SequenceParser(); var kleeneOpt = (~((Parser)'+' | '?' | '*')).WithName("kleene"); regExpItem = ((setLiteral & kleeneOpt) | (setName & kleeneOpt) | (terminal.Named("terminal") & kleeneOpt) | ('(' & regExp2.Named("regExp2") & ')' & kleeneOpt)).WithName("regExpItem"); var regExpSeq = (+regExpItem).WithName("regExpSeq"); regExp2.Items.Add(regExpSeq); regExp2.Items.Add(-('|' & regExpSeq)); regExp = (regExpSeq & -(nlOpt & '|' & regExpSeq)).WithName("regExp"); var terminalName = +terminal; terminalDecl = (terminalName.Named("name") & nlOpt & '=' & regExp & nl).WithName("terminalDecl"); // Rule Definition symbol = (terminal.Named("terminal") | nonterminal.Named("nonterminal")).WithName("symbol"); handle = (-symbol).WithName("handle"); var handles = handle & -(nlOpt & '|' & handle); ruleDecl = (nonterminal.Named("name") & nlOpt & "::=" & handles & nl).WithName("ruleDecl"); // Rules var definitionDecl = parameter | setDecl | terminalDecl | ruleDecl; var content = -definitionDecl; this.Inner = nlOpt & content & nlOpt; Parser.DefaultSeparator = oldSeparator; AttachEvents(); }
void AttachEvents() { // attach logic to parsers parameter.PreMatch += m => { var name = m["name"]["value"].Text; var value = m["body"].Text; definition.Properties[name] = value; bool val; if (string.Equals("Auto Whitespace", name, StringComparison.OrdinalIgnoreCase) && bool.TryParse(value, out val) && !val) definition.Whitespace = null; }; ruleDecl.Matched += m => { var name = m["name"]["value"].Text; bool addWhitespace = name == definition.GrammarName; var parser = Alternative(m, "handle", r => Sequence(r, "symbol", Symbol, addWhitespace)); definition.Rules[name].Inner = parser; }; ruleDecl.PreMatch += m => { var name = m["name"]["value"].Text; UnaryParser parser; if (name == definition.GrammarName) parser = new Grammar(name); else parser = new UnaryParser(name); definition.Rules.Add(parser.Name, parser); }; terminalDecl.Matched += m => { var inner = Sequence(m, "regExp", RegExp); var parser = m.Tag as UnaryParser; if (parser != null) parser.Inner = inner; var groupParser = m.Tag as GroupParser; var name = m["name"].Text; if (groupParser != null) { if (name.EndsWith(" Start", StringComparison.Ordinal)) groupParser.Start = inner; else if (name.EndsWith(" End", StringComparison.Ordinal)) groupParser.End = inner; else if (name.EndsWith(" Line", StringComparison.Ordinal)) groupParser.Line = inner; var count = name.EndsWith(" Start", StringComparison.Ordinal) ? 6 : name.EndsWith(" Line", StringComparison.Ordinal) ? 5 : name.EndsWith(" End", StringComparison.Ordinal) ? 4 : 0; name = name.Substring(0, name.Length - count); } if (name.Equals("Comment", StringComparison.OrdinalIgnoreCase) || name.Equals("Whitespace", StringComparison.OrdinalIgnoreCase) ) { definition.ClearSeparator(); } }; terminalDecl.PreMatch += m => { var name = m["name"].Text; if (name.EndsWith(" Start", StringComparison.Ordinal) || name.EndsWith(" End", StringComparison.Ordinal) || name.EndsWith(" Line", StringComparison.Ordinal)) { Parser parser; var count = name.EndsWith(" Start", StringComparison.Ordinal) ? 6 : name.EndsWith(" Line", StringComparison.Ordinal) ? 5 : name.EndsWith(" End", StringComparison.Ordinal) ? 4 : 0; name = name.Substring(0, name.Length - count); if (definition.Terminals.TryGetValue(name, out parser)) { parser = parser as GroupParser ?? new GroupParser(); } else parser = new GroupParser(); m.Tag = definition.Terminals[name] = parser; } else m.Tag = definition.Terminals[name] = new UnaryParser(name); }; setDecl.PreMatch += m => { var parser = SetMatch(m["setExp"]); definition.Sets[m["setName"]["value"].Text] = parser; m.Tag = parser; }; }