/// <summary> /// run step 123. /// </summary> /// <returns></returns> public override Expr Parse() { /* * [ * name | pages | author * 'c#' | 150 | 'microsoft' * 'ruby' | 140 | 'matz' * 'fluent' | 100 | 'codehelix' * ]; * [ * name | pages | author * 'c#' , 150 , 'microsoft' * 'ruby' , 140 , 'matz' * 'fluent' , 100 , 'codehelix' * ]; */ var startToken = _tokenIt.NextToken; // 1. Move past "[" _tokenIt.Advance(1, true); var columnNames = new List <string>(); var token = _tokenIt.NextToken.Token; while (!Token.IsNewLine(token) && !_tokenIt.IsEnded) { // Expect column name. var columnName = _tokenIt.ExpectId(false); columnNames.Add(columnName); _tokenIt.Advance(1, false); // "|" pipe to separate column names. if (_tokenIt.NextToken.Token == Tokens.Pipe) { _tokenIt.Advance(1, false); } else if (_tokenIt.NextToken.Token != Tokens.NewLine) { throw _tokenIt.BuildSyntaxExpectedException("| or new line"); } token = _tokenIt.NextToken.Token; } if (_tokenIt.IsEnded) { throw _tokenIt.BuildEndOfScriptException(); } // Hit new line? _tokenIt.Advance(); var records = new List <List <Tuple <string, Expr> > >(); var record = new List <Tuple <string, Expr> >(); var colIndex = 0; Token firstColumnDataDelimiter = null; // Build up all the records. while (token != Tokens.RightBracket && !_tokenIt.IsEnded) { // 1. Get the column value: 'C#' var exp = _parser.ParseExpression(_endTokens, true, passNewLine: false); var colName = columnNames[colIndex]; record.Add(new Tuple <string, Expr>(colName, exp)); // 2. Is the next one a | or new line ? //_tokenIt.Advance(1, false); token = _tokenIt.NextToken.Token; // 3. If "|" or "," it separates expression/column values. if (firstColumnDataDelimiter == null && token == Tokens.Pipe || token == Tokens.Comma) { firstColumnDataDelimiter = token; } if (token == firstColumnDataDelimiter) { _tokenIt.Advance(1, false); colIndex++; } // 4. If Newline, end of current record. else if (token == Tokens.NewLine) { records.Add(record); record = new List <Tuple <string, Expr> >(); _tokenIt.Advance(); colIndex = 0; } else if (token == Tokens.RightBracket) { records.Add(record); record = new List <Tuple <string, Expr> >(); colIndex = 0; } else { throw _tokenIt.BuildSyntaxExpectedException("| or new line"); } token = _tokenIt.NextToken.Token; } _tokenIt.Expect(Tokens.RightBracket); // Now finally build array of maps. var array = new List <Expr>(); foreach (var rec in records) { var item = Exprs.Map(rec, startToken); array.Add(item); } var arrayExp = Exprs.Array(array, startToken); return(arrayExp); }