public ExprOp ParseOrExpr(QueryLexerTokenKind tokContext) { ExprOp node = ParseAndExpr(tokContext); if (node != null) { while (true) { QueryLexerToken tok = Lexer.NextToken(tokContext); if (tok.Kind == QueryLexerTokenKind.TOK_OR) { ExprOp prev = node; node = new ExprOp(OpKindEnum.O_OR); node.Left = prev; node.Right = ParseAndExpr(tokContext); if (node.Right == null) { throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol())); } } else { Lexer.PushToken(tok); break; } } return(node); } return(null); // new ExprOp(); }
public ExprOp ParseQueryTerm(QueryLexerTokenKind tokContext) { ExprOp node = null; QueryLexerToken tok = Lexer.NextToken(tokContext); switch (tok.Kind) { case QueryLexerTokenKind.TOK_SHOW: case QueryLexerTokenKind.TOK_ONLY: case QueryLexerTokenKind.TOK_BOLD: case QueryLexerTokenKind.TOK_FOR: case QueryLexerTokenKind.TOK_SINCE: case QueryLexerTokenKind.TOK_UNTIL: case QueryLexerTokenKind.END_REACHED: Lexer.PushToken(tok); break; case QueryLexerTokenKind.TOK_CODE: case QueryLexerTokenKind.TOK_PAYEE: case QueryLexerTokenKind.TOK_NOTE: case QueryLexerTokenKind.TOK_ACCOUNT: case QueryLexerTokenKind.TOK_META: case QueryLexerTokenKind.TOK_EXPR: node = ParseQueryTerm(tok.Kind); if (node == null) { throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol())); } break; case QueryLexerTokenKind.TERM: if (String.IsNullOrEmpty(tok.Value)) { throw new InvalidOperationException("term"); } switch (tokContext) { case QueryLexerTokenKind.TOK_EXPR: node = new Expr(tok.Value).Op; break; case QueryLexerTokenKind.TOK_META: { node = new ExprOp(OpKindEnum.O_CALL); ExprOp ident = new ExprOp(OpKindEnum.IDENT); ident.AsIdent = "has_tag"; node.Left = ident; ExprOp arg1 = new ExprOp(OpKindEnum.VALUE); arg1.AsValue = Value.Get(new Mask(tok.Value)); tok = Lexer.PeekToken(tokContext); if (tok.Kind == QueryLexerTokenKind.TOK_EQ) { tok = Lexer.NextToken(tokContext); tok = Lexer.NextToken(tokContext); if (tok.Kind != QueryLexerTokenKind.TERM) { throw new ParseError(ParseError.ParseError_MetadataEqualityOperatorNotFollowedByTerm); } ExprOp arg2 = new ExprOp(OpKindEnum.VALUE); if (String.IsNullOrEmpty(tok.Value)) { throw new InvalidOperationException(); } arg2.AsValue = Value.Get(new Mask(tok.Value)); node.Right = ExprOp.NewNode(OpKindEnum.O_SEQ, ExprOp.NewNode(OpKindEnum.O_CONS, arg1, arg2)); } else { node.Right = arg1; } break; } default: { node = new ExprOp(OpKindEnum.O_MATCH); ExprOp ident = new ExprOp(OpKindEnum.IDENT); switch (tokContext) { case QueryLexerTokenKind.TOK_ACCOUNT: ident.AsIdent = "account"; break; case QueryLexerTokenKind.TOK_PAYEE: ident.AsIdent = "payee"; break; case QueryLexerTokenKind.TOK_CODE: ident.AsIdent = "code"; break; case QueryLexerTokenKind.TOK_NOTE: ident.AsIdent = "note"; break; default: throw new InvalidOperationException(); } ExprOp mask = new ExprOp(OpKindEnum.VALUE); mask.AsValue = Value.Get(new Mask(tok.Value)); node.Left = ident; node.Right = mask; break; } } break; case QueryLexerTokenKind.LPAREN: node = ParseQueryExpr(tokContext, true); tok = Lexer.NextToken(tokContext); if (tok.Kind != QueryLexerTokenKind.RPAREN) { tok.Expected(')'); } break; default: Lexer.PushToken(tok); break; } return(node); }
public ExprOp ParseUnaryExpr(QueryLexerTokenKind tokContext) { ExprOp node = null; QueryLexerToken tok = Lexer.NextToken(tokContext); switch (tok.Kind) { case QueryLexerTokenKind.TOK_NOT: { ExprOp term = ParseQueryTerm(tokContext); if (term == null) { throw new ParseError(String.Format(ParseError.ParseError_OperatorNotFollowedByArgument, tok.Symbol())); } node = new ExprOp(OpKindEnum.O_NOT); node.Left = term; break; } default: Lexer.PushToken(tok); node = ParseQueryTerm(tokContext); break; } return(node); }