private void Parse(string s) { Children.Clear(); Subindices.Clear(); if (s.Length >= 2 && s[0] == '[' && s[s.Length - 1] == ']') { Parse(new Tokenizer(s.Substring(1, s.Length - 2))); } else { var t = JToken.Parse(s); SetContent(t); } }
private void Parse(Tokenizer lexer) { var tok = lexer.NextToken(); if (tok.Type == TokenTypes.Number) { // Simple value Type = ExpressionTypes.Number; _content = tok.Content; return; } if (tok.Type == TokenTypes.String) { // Simple value Type = ExpressionTypes.String; _content = tok.Content; return; } if (tok.Type == TokenTypes.Identifier) { // Function call _content = tok.Content; tok = lexer.NextToken(); if (tok.Type != TokenTypes.Lbrace) { throw new ExpressionException("Syntax error"); } bool closed = false; while (!lexer.Completed) { tok = lexer.LookAhead(); if (tok.Type == TokenTypes.Rbrace) { // Consume the ')' lexer.NextToken(); closed = true; break; } // This is an oprand Children.Add(new Expression(lexer)); if (lexer.LookAhead().Type == TokenTypes.Comma) { // Consume next comma lexer.NextToken(); } } if (!closed) { throw new ExpressionException("Syntax error"); } // Look ahead for trailing properties if (lexer.LookAhead().Type == TokenTypes.Dot) { // There are trailing properties while (!lexer.Completed) { if (lexer.LookAhead().Type == TokenTypes.Dot) { // Property "x.y" // Consume '.' lexer.NextToken(); tok = lexer.NextToken(); if (tok.Type != TokenTypes.Identifier) { throw new ExpressionException("Syntax error"); } Subindices.Add(new Subindex(tok.Content)); } else if (lexer.LookAhead().Type == TokenTypes.Lbracket) { // Array Index // Consume '[' lexer.NextToken(); var idx = new Expression(lexer); Subindices.Add(new Subindex(idx)); // Consume and check ']' if (lexer.NextToken().Type != TokenTypes.Rbracket) { throw new ExpressionException("Syntax error"); } } else { // properties list ended break; } } } Type = ExpressionTypes.Function; return; } throw new ExpressionException("Syntax error"); }