예제 #1
0
		public JsonGrammar()
			: base("json")
		{
			EnableMatchEvents = false;
			CaseSensitive = true;

			// terminals
			var jstring = new StringParser { AllowEscapeCharacters = true, Name = "string" };
			var jnumber = new NumberParser { AllowExponent = true, AllowSign = true, AllowDecimal = true, Name = "number" };
			var jboolean = new BooleanTerminal { Name = "bool", TrueValues = new string[] { "true" }, FalseValues = new string[] { "false" }, CaseSensitive = false };
			var jname = new StringParser { AllowEscapeCharacters = true, Name = "name" };
			var jnull = new LiteralTerminal { Value = "null", Name = "null", CaseSensitive = false };
			var ws = new RepeatCharTerminal(char.IsWhiteSpace);
			var commaDelimiter = new RepeatCharTerminal(new RepeatCharItem(char.IsWhiteSpace), ',', new RepeatCharItem(char.IsWhiteSpace));

			// nonterminals (things we're interested in getting back)
			var jobject = new SequenceParser { Name = "object" }; 
			var jarray = new SequenceParser { Name = "array" };
			var jprop = new SequenceParser { Name = "property" };

			// rules
			var jvalue = jstring | jnumber | jobject | jarray | jboolean | jnull;
			jobject.Add("{", (-jprop).SeparatedBy(commaDelimiter), "}");
			jprop.Add(jname, ":", jvalue);
			jarray.Add("[", (-jvalue).SeparatedBy(commaDelimiter), "]");

			// separate sequence and repeating parsers by whitespace
			jvalue.SeparateChildrenBy(ws, false);

			// allow whitespace before and after the initial object or array
			this.Inner = ws & (jobject | jarray) & ws;
		}
예제 #2
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;
		}
예제 #3
0
		public void Initialize(MarkdownGrammar grammar)
		{
			var prefix = "[" & (+Terminals.Set("]\n\r").Inverse()).WithName("id") & "]:";
			var link = (+Terminals.WhiteSpace.Inverse()).WithName("link");
			var title = new StringParser { Name = "title", BeginQuoteCharacters = "\"'(".ToCharArray(), EndQuoteCharacters = "\"')".ToCharArray() };

			Add(Terms.sp.Repeat(0, 3), prefix, Terms.ows, link, Terms.ows, ~title, +Terms.blankLine | Terms.eof);
		}
예제 #4
0
 protected StringParser(StringParser other, ParserCloneArgs args)
     : base(other, args)
 {
     this.BeginQuoteCharacters = other.BeginQuoteCharacters != null ? (char[])other.BeginQuoteCharacters.Clone() : null;
     this.EndQuoteCharacters = other.EndQuoteCharacters != null ? (char[])other.EndQuoteCharacters.Clone() : null;
     this.AllowDoubleQuote = other.AllowDoubleQuote;
     this.AllowEscapeCharacters = other.AllowEscapeCharacters;
     this.AllowNonQuoted = other.AllowNonQuoted;
     this.NonQuotedLetter = args.Clone(other.NonQuotedLetter);
 }
		public void TestDoubleQuoting()
		{
			var sample = "\"string\"\" ''1'\",'string'' \"\"2\"'";

			var grammar = new Grammar();
			var str = new StringParser { AllowDoubleQuote = true };

			grammar.Inner = (+str.Named("str")).SeparatedBy(",");

			var match = grammar.Match(sample);
			Assert.IsTrue(match.Success, match.ErrorMessage);
			CollectionAssert.AreEquivalent(new string[] { "string\" ''1'", "string' \"\"2\"" }, match.Find("str").Select(m => str.GetValue(m)));
		}
		public void TestEscaping()
		{
			var sample = "\"string\\'\\\"\\0\\a\\b\\f\\n\\r\\t\\v\\x123\\u1234\\U00001234 1\",'string\\'\\\"\\0\\a\\b\\f\\n\\r\\t\\v\\x123\\u1234\\U00001234 2'";

			var grammar = new Grammar();
			var str = new StringParser { AllowEscapeCharacters = true  };

			grammar.Inner = (+str.Named("str")).SeparatedBy(",");

			var match = grammar.Match(sample);
			Assert.IsTrue(match.Success, match.ErrorMessage);
			var values = match.Find("str").Select(m => str.GetValue(m)).ToArray();
			CollectionAssert.AreEquivalent(new string[] { "string\'\"\0\a\b\f\n\r\t\v\x123\u1234\U00001234 1", "string\'\"\0\a\b\f\n\r\t\v\x123\u1234\U00001234 2" }, values);
		}
		public void TestErrorConditionsWithOptions()
		{
			var samples = new string[] { "string 1", "\"string 2", "'string 3", "'string ''4", "string5'", "string6\"", "\"string\\\"7" };

			var grammar = new Grammar();
			var str = new StringParser { AllowDoubleQuote = true, AllowNonQuoted = true, AllowEscapeCharacters = true };

			grammar.Inner = str.Named("str");

			foreach (var sample in samples)
			{
				var match = grammar.Match(sample);
				Assert.IsFalse(match.Success, "Should not match string {0}", sample);
			}
		}
예제 #8
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();
		}