internal static ExpressionBase Parse(PositionalTokenizer tokenizer, int line = 0, int column = 0) { SkipWhitespace(tokenizer); var dict = new DictionaryExpression(); while (tokenizer.NextChar != '}') { var key = ExpressionBase.ParseClause(tokenizer); if (key.Type == ExpressionType.ParseError) { return(key); } SkipWhitespace(tokenizer); if (tokenizer.NextChar != ':') { ParseError(tokenizer, "Expecting colon following key expression"); break; } tokenizer.Advance(); SkipWhitespace(tokenizer); var value = ExpressionBase.ParseClause(tokenizer); if (value.Type == ExpressionType.ParseError) { break; } dict.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = key, Value = value }); SkipWhitespace(tokenizer); if (tokenizer.NextChar == '}') { break; } if (tokenizer.NextChar != ',') { ParseError(tokenizer, "Expecting comma between entries"); break; } tokenizer.Advance(); SkipWhitespace(tokenizer); } tokenizer.Advance(); return(dict); }
/// <summary> /// Gets the next expression from the input. /// </summary> /// <returns>The next expression, <c>null</c> if at end of file.</returns> public static ExpressionBase Parse(PositionalTokenizer tokenizer) { SkipWhitespace(tokenizer); if (tokenizer.NextChar == '\0') { return(new ParseErrorExpression("Unexpected end of script", tokenizer.Line, tokenizer.Column, tokenizer.Line, tokenizer.Column)); } var line = tokenizer.Line; var column = tokenizer.Column; var clause = ExpressionBase.ParseClause(tokenizer); if (clause.Type == ExpressionType.ParseError || clause.Type == ExpressionType.Comment) { return(clause); } var clauseEndLine = tokenizer.Line; var clauseEndColumn = tokenizer.Column; SkipWhitespace(tokenizer); var joinerLine = tokenizer.Line; var joinerColumn = tokenizer.Column; switch (tokenizer.NextChar) { case '+': tokenizer.Advance(); clause = ParseMathematic(tokenizer, clause, MathematicOperation.Add, joinerLine, joinerColumn); break; case '-': tokenizer.Advance(); clause = ParseMathematic(tokenizer, clause, MathematicOperation.Subtract, joinerLine, joinerColumn); break; case '*': tokenizer.Advance(); clause = ParseMathematic(tokenizer, clause, MathematicOperation.Multiply, joinerLine, joinerColumn); break; case '/': tokenizer.Advance(); clause = ParseMathematic(tokenizer, clause, MathematicOperation.Divide, joinerLine, joinerColumn); break; case '%': tokenizer.Advance(); clause = ParseMathematic(tokenizer, clause, MathematicOperation.Modulus, joinerLine, joinerColumn); break; case '=': tokenizer.Advance(); if (tokenizer.NextChar == '=') { tokenizer.Advance(); clause = ParseComparison(tokenizer, clause, ComparisonOperation.Equal, joinerLine, joinerColumn); } else { clause = ParseAssignment(tokenizer, clause, joinerLine, joinerColumn); } break; case '!': tokenizer.Advance(); if (tokenizer.NextChar != '=') { clause = ParseError(tokenizer, "= expected following !", joinerLine, joinerColumn); } else { tokenizer.Advance(); clause = ParseComparison(tokenizer, clause, ComparisonOperation.NotEqual, joinerLine, joinerColumn); } break; case '<': tokenizer.Advance(); if (tokenizer.NextChar == '=') { tokenizer.Advance(); clause = ParseComparison(tokenizer, clause, ComparisonOperation.LessThanOrEqual, joinerLine, joinerColumn); } else { clause = ParseComparison(tokenizer, clause, ComparisonOperation.LessThan, joinerLine, joinerColumn); } break; case '>': tokenizer.Advance(); if (tokenizer.NextChar == '=') { tokenizer.Advance(); clause = ParseComparison(tokenizer, clause, ComparisonOperation.GreaterThanOrEqual, joinerLine, joinerColumn); } else { clause = ParseComparison(tokenizer, clause, ComparisonOperation.GreaterThan, joinerLine, joinerColumn); } break; case '&': tokenizer.Advance(); if (tokenizer.NextChar != '&') { clause = ParseError(tokenizer, "& expected following &", joinerLine, joinerColumn); } else { tokenizer.Advance(); clause = ParseConditional(tokenizer, clause, ConditionalOperation.And, joinerLine, joinerColumn); if (clause.Type == ExpressionType.ParseError) { return(clause); } } break; case '|': tokenizer.Advance(); if (tokenizer.NextChar != '|') { clause = ParseError(tokenizer, "| expected following |", joinerLine, joinerColumn); } else { tokenizer.Advance(); clause = ParseConditional(tokenizer, clause, ConditionalOperation.Or, joinerLine, joinerColumn); if (clause.Type == ExpressionType.ParseError) { return(clause); } } break; default: if (clause.EndColumn == 0) { clause.EndLine = clauseEndLine; clause.EndColumn = clauseEndColumn; } return(clause); } clause = clause.Rebalance(); Debug.Assert(clause.Line != 0); Debug.Assert(clause.Column != 0); Debug.Assert(clause.EndLine != 0); Debug.Assert(clause.EndColumn != 0); return(clause); }