예제 #1
0
		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;
		}
예제 #2
0
		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);
		}
예제 #3
0
 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);
 }
예제 #4
0
 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;
		}
예제 #6
0
		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);
		}
예제 #7
0
		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));
			}
		}
예제 #8
0
		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;
		}
예제 #9
0
		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();
		}
예제 #10
0
파일: EbnfGrammar.cs 프로젝트: Myvar/Eclang
 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;
     }
 }