internal Tailcall ParseItemAsDictionary(ObjectNode context, string prefix = null) { bool justOneItem = context.Selector.Name == "" || context.Selector.Name == "*"; switch (Type) { case TokenType.OpenBrace: return(ParseItemsInDictionary(context, prefix: prefix)); case TokenType.EmbeddedInstruction: context.SetNodeValue(new Instruction(context, Token.Data, new SourceLocation(Token, Filename))); if (NextAfter(WhiteSpaceOrComments) == TokenType.Semicolon) { return(Continue()); } throw Fail(ErrorCode.TokenNotExpected, "Token '{0}' not expected after Instruction. Looking for ';'"); case TokenType.ColonEquals: // expecting one of: // - an object declaration { } // - an instruction // - an RValue to be used as the value source for an object. switch (NextAfter(WhiteSpaceOrComments)) { case TokenType.OpenBrace: return(ParseItemsInDictionary(context, prefix: prefix)); case TokenType.EmbeddedInstruction: context.SetNodeValue(new Instruction(context, Token.Data, new SourceLocation(Token, Filename))); if (NextAfter(WhiteSpaceOrComments) == TokenType.Semicolon) { return(Continue()); } throw Fail(ErrorCode.TokenNotExpected, "Token '{0}' not expected after Instruction. Looking for ';'"); } // hmm. didn't seem to be one of the first two types. Try to grab it as an RValue then. Rewind(); context.SetNodeValue(ParseRValue(context, Semicolon, context)); return(Continue()); } throw Fail(ErrorCode.TokenNotExpected, "Token '{0}' not expected after Identifier. Looking for '{' , ':=' or Instruction."); }
/// <exception cref="ParseException">Token '{0}' not expected in object declaration</exception> private Tailcall ParseItemsInDictionary(ObjectNode context, Continuation onComplete = null, bool justOneItem = false, string prefix = null) { switch (NextAfter(justOneItem ? WhiteSpaceOrComments : WhiteSpaceCommentsOrSemicolons, onComplete != null)) { case TokenType.Identifier: if (Data == "@alias") { ParseAlias(context); return(ParseItemsInDictionary(context, onComplete, prefix: prefix)); } break; case TokenType.Pound: // metadata entry ParseMetadataItem(context); return(ParseItemsInDictionary(context, onComplete, prefix: prefix)); case TokenType.OpenParenthesis: //var iValue = ParseMatrixForEach(context, Semicolon, new ObjectIterator(context, new SourceLocation(Token, Filename)){Prefix = prefix ?? (context.IndexValue-1).ToString()}); // iValue is the ObjectIterator. var n = new ExpansionPropertyNode(); context.Properties[Guid.NewGuid().ToString()] = n; // unique node for the item n.ObjectIterator = ParseMatrixForEach(context, Semicolon, new ObjectIterator(context, new SourceLocation(Token, Filename)) { Prefix = prefix ?? (context.CurrentIndex).ToString() }) as ObjectIterator; return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix)); case TokenType.CloseBrace: return((onComplete ?? Continue)()); case TokenType.Eof: // we should only get here if we discovered the EOF outside of anything. return(onComplete); } Rewind(); var selector = ParseSelector(MemberTerminator); if (selector.Name.StartsWith(".")) { selector = new Selector((prefix ?? string.Empty) + context.NextIndexValue + selector.Name, selector.Parameter, selector.SourceLocation); } switch (Type) { case TokenType.Dot: case TokenType.Identifier: { // if we're pointing to an identifier or a dot, we're about to take whatever is next, and include it in a dictionary as a way of syntatic sugar. return(ParseItemsInDictionary(context.Children[selector], () => ParseItemsInDictionary(context, onComplete, prefix: prefix), true)); } case TokenType.OpenBrace: { if (justOneItem) { return(ParseItemsInDictionary(context.Children[selector], (onComplete ?? Continue))); } return(ParseItemsInDictionary(context.Children[selector], () => ParseItemsInDictionary(context, onComplete, prefix: prefix))); } case TokenType.Colon: { var p = context.Properties[selector]; p.SetCollection(ParseRValue(context, SemicolonCommaOrCloseBrace, p)); return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix)); } case TokenType.PlusEquals: { var p = context.Properties[selector]; p.AddToCollection(ParseRValue(context, Semicolon, p)); return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix)); } // same as the part in ParseItemAsDictionary() case TokenType.EmbeddedInstruction: var n = context.Children[selector]; n.SetNodeValue(new Instruction(n, Token.Data, new SourceLocation(Token, Filename))); if (NextAfter(WhiteSpaceOrComments) == TokenType.Semicolon) { return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix)); } throw Fail(ErrorCode.TokenNotExpected, "Token '{0}' not expected after Instruction. Looking for ';'"); // same as the part in ParseItemAsDictionary() case TokenType.ColonEquals: // expecting one of: // - an object declaration { } // - an instruction // - an RValue to be used as the value source for an object. switch (NextAfter(WhiteSpaceOrComments)) { case TokenType.OpenBrace: if (justOneItem) { return(ParseItemsInDictionary(context.Children[selector], (onComplete ?? Continue))); } return(ParseItemsInDictionary(context.Children[selector], () => ParseItemsInDictionary(context, onComplete, prefix: prefix))); case TokenType.EmbeddedInstruction: var no = context.Children[selector]; no.SetNodeValue(new Instruction(no, Token.Data, new SourceLocation(Token, Filename))); if (NextAfter(WhiteSpaceOrComments) == TokenType.Semicolon) { return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix)); } throw Fail(ErrorCode.TokenNotExpected, "Token '{0}' not expected after Instruction. Looking for ';'"); } // hmm. didn't seem to be one of the first two types. Try to grab it as an RValue then. Rewind(); context.SetNodeValue(ParseRValue(context, Semicolon, context)); return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix)); case TokenType.Equal: { var p = context.Properties[selector]; p.SetValue(ParseRValue(context, SemicolonCommaOrCloseBrace, p)); return(justOneItem ? (onComplete ?? Continue)() : ParseItemsInDictionary(context, onComplete, prefix: prefix)); } } throw Fail(ErrorCode.TokenNotExpected, "Token '{0}' not expected in object declaration"); }