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; }
public void Initialize(MarkdownGrammar grammar) { var content = new RepeatParser().Until(Terms.eolorf); content.Name = "content"; var line = grammar.Indent & content; Inner = line; this.Minimum = 1; this.SeparatedBy(+(Terms.ows & Terms.eol.Named("sep"))).Until(Terms.EndOfSection(line.Not()), true); }
protected RepeatParser(RepeatParser other, ParserCloneArgs args) : base(other, args) { Minimum = other.Minimum; Maximum = other.Maximum; Until = args.Clone(other.Until); SkipUntil = other.SkipUntil; CaptureUntil = other.CaptureUntil; Separator = args.Clone(other.Separator); }
public void Initialize(MarkdownGrammar grammar) { this.grammar = grammar; var prefix = (grammar.Prefix & -Terms.sp) & Terminals.Literal(">"); var value = new RepeatParser(1).Until(Terms.eolorf, true); prefix.Name = "prefix"; value.Name = "value"; this.Inner = prefix.Separate() & Terms.ows & value & -Terms.blankLine; this.Minimum = 1; }
public MarkdownGrammar() : base("markdown") { EnableMatchEvents = false; indent = new RepeatParser(Terms.indent, 1, 1); prefix = new RepeatParser(Terms.indent, 0, 0); prefixsp = new RepeatParser(Terms.sporht, 0, 0); encoding = new MarkdownEncoding(); encoding.Initialize(this); replacementsOnly = new ReplacementParser(this); replacements = new ReplacementParser(this); var reps = GetReplacements().ToArray(); replacementsOnly.Add(reps, false); replacements.Add(reps, true); replacements.Add(Terminals.AnyChar); this.Inner = -replacements; SetError<Parser>(false); }
Parser Primary(Match match, bool isTerminal) { var child = match.Matches.FirstOrDefault(r => r.Name != null); if (child == null) throw new FormatException(string.Format("Primary must have a child. Text: '{0}'", match.Text)); Parser parser; switch (child.Name) { case "grouped sequence": return new UnaryParser(DefinitionList(child["definition list"], isTerminal)); case "optional sequence": return new OptionalParser(DefinitionList(child["definition list"], isTerminal)); case "repeated sequence": var repeat = new RepeatParser(DefinitionList(child["definition list"], isTerminal), 0); if (!isTerminal) repeat.Separator = separator; return repeat; case "meta identifier": if (!parserLookup.TryGetValue(child.Text, out parser)) { parser = parserLookup[child.Text] = Terminals.LetterOrDigit.Repeat().Named(child.Text); } return parser; case "terminal string": return new LiteralTerminal(child.StringValue); case "hex character": return new SingleCharTerminal((char)int.Parse(child.Text.Substring(2), NumberStyles.HexNumber)); case "character set": return CharacterSet(child); case "special sequence": var name = child["name"].Text.Trim(); if (specialLookup.TryGetValue(name, out parser)) return parser; else return null; default: throw new FormatException(string.Format("Could not parse child with name '{0}'", child.Name)); } }
Parser Factor(Match match, bool isTerminal) { var primary = Primary(match["primary"], isTerminal); var cardinality = match["cardinality"]; if (cardinality) { switch (cardinality.Text) { case "?": primary = new OptionalParser(primary); break; case "*": primary = new RepeatParser(primary, 0); break; case "+": primary = new RepeatParser(primary, 1); break; default: throw new FormatException(string.Format("Cardinality '{0}' is unknown", cardinality.Text)); break; } } var integer = match["integer"]; if (integer) return new RepeatParser(primary, Int32.Parse(integer.Text)); else return primary; }
public EbnfGrammar(EbnfStyle style) : base("ebnf") { Style = style; DefineCommonNonTerminals = true; GenerateSpecialSequences(); // terminals var comment = style.HasFlag(EbnfStyle.BracketComments) ? new GroupParser("(*", "*)") : new GroupParser("/*", "*/"); var ows = -(Terminals.WhiteSpace | comment); var rws = +(Terminals.WhiteSpace | comment); var hex_character = ("#x" & +Terminals.HexDigit); var character = (("\\" & Terminals.AnyChar) | hex_character | Terminals.AnyChar.Except("]")).WithName("character"); var character_range = (character & "-" & character).WithName("character range"); var character_set = ("[" & ~(Parser)"^" & +(character_range | character) & "]").WithName("character set"); var terminal_string = new StringParser { QuoteCharacters = new [] { '\"', '\'', '’' }, Name = "terminal string" }; var special_sequence = ("?" & (+Terminals.AnyChar).Until("?").WithName("name") & "?").WithName("special sequence"); var meta_identifier_terminal = Terminals.Letter & -(Terminals.LetterOrDigit | '_'); var integer = new NumberParser().WithName("integer"); // nonterminals var definition_list = new RepeatParser(0).WithName("definition list"); var single_definition = new RepeatParser(1).WithName("single definition"); var term = new SequenceParser().WithName("term"); var primary = new AlternativeParser().WithName("primary"); var exception = new UnaryParser("exception"); var factor = new SequenceParser().WithName("factor"); var meta_identifier = new RepeatParser(1).WithName("meta identifier"); var syntax_rule = new SequenceParser().WithName("syntax rule"); var rule_equals = new AlternativeParser().WithName("equals"); Parser meta_reference = meta_identifier; Parser grouped_sequence = ("(" & ows & definition_list & ows & ")").WithName("grouped sequence"); if (style.HasFlag(EbnfStyle.SquareBracketAsOptional)) { primary.Add(("[" & ows & definition_list & ows & "]").WithName("optional sequence")); } if (!style.HasFlag(EbnfStyle.CardinalityFlags)) { var repeated_sequence = ("{" & ows & definition_list & ows & "}").WithName("repeated sequence"); primary.Add(repeated_sequence); } // rules meta_identifier.Inner = meta_identifier_terminal; meta_identifier.Separator = +(Terminals.SingleLineWhiteSpace); if (!style.HasFlag(EbnfStyle.CommaSeparator)) { // w3c identifiers must be a single word meta_identifier.Maximum = 1; meta_reference = meta_reference.NotFollowedBy(ows & rule_equals); } primary.Add(grouped_sequence, meta_reference, terminal_string, special_sequence); if (style.HasFlag(EbnfStyle.CharacterSets) && !style.HasFlag(EbnfStyle.SquareBracketAsOptional)) { // w3c supports character sets primary.Add(hex_character.Named("hex character")); primary.Add(character_set); } if (style.HasFlag(EbnfStyle.NumericCardinality)) factor.Add(~(integer & ows & "*" & ows)); factor.Add(primary); if (style.HasFlag(EbnfStyle.CardinalityFlags)) { // w3c defines cardinality at the end of a factor var flags = style.HasFlag(EbnfStyle.SquareBracketAsOptional) ? "*+" : "?*+"; factor.Add(~(ows & Terminals.Set(flags).WithName("cardinality"))); } term.Add(factor, ~(ows & "-" & ows & exception)); exception.Inner = term; single_definition.Inner = term; single_definition.Separator = style.HasFlag(EbnfStyle.CommaSeparator) ? (Parser)(ows & "," & ows) : ows; definition_list.Inner = single_definition; definition_list.Separator = ows & "|" & ows; rule_equals.Add(style.HasFlag(EbnfStyle.DoubleColonEquals) ? "::=" : "=", ":="); syntax_rule.Add(meta_identifier, ows, rule_equals, ows, definition_list); if (style.HasFlag(EbnfStyle.SemicolonTerminator)) syntax_rule.Add(ows, ";"); // iso rules are terminated by a semicolon var syntax_rules = +syntax_rule; syntax_rules.Separator = style.HasFlag(EbnfStyle.SemicolonTerminator) ? ows : rws; Inner = ows & syntax_rules & ows; AttachEvents(); }
Parser Primary(Match match, bool isTerminal) { var child = match.Matches.FirstOrDefault(); if (child == null) return null; Parser parser; switch (child.Name) { case "grouped sequence": return new UnaryParser(DefinitionList(child["definition list"], isTerminal)); case "optional sequence": return new OptionalParser(DefinitionList(child["definition list"], isTerminal)); case "repeated sequence": var repeat = new RepeatParser(DefinitionList(child["definition list"], isTerminal), 0); if (!isTerminal) repeat.Separator = separator; return repeat; case "meta identifier": if (!parserLookup.TryGetValue(child.Text, out parser)) { parser = parserLookup[child.Text] = Terminals.LetterOrDigit.Repeat().Named(child.Text); } return parser; case "terminal string": return new LiteralTerminal(child["value"].Text); case "special sequence": var name = child["name"].Text.Trim(); if (specialLookup.TryGetValue(name, out parser)) return parser; else return null; default: return null; } }