/// <summary> /// Transform a compressed array of tokens into a AST. /// </summary> /// <param name="tokens"></param> /// <returns></returns> public GroupNode BuildAst(IList<Token> tokens) { var context = new NodeContext(); var root = new ParenthesisGroupNode(); context.PushParent(root); BuildGroups(tokens, context); if (context.ParentCount > 1) throw new Exception(); if (context.LastParent != root) throw new Exception(); BuildOperators(root); BuildUnaryBranches(root); BuildBooleanBranches(root); return root; }
private void BuildGroups(IList<Token> tokens, NodeContext context) { for (int i = 0; i < tokens.Count; i++) { var token = tokens[i]; switch (token.Type) { case TokenType.Word: { var node = new TermNode(token.Text); context.AddChild(node); } break; case TokenType.BooleanAnd: { var node = new BooleanNode(BooleanType.And); context.AddChild(node); } break; case TokenType.BooleanOr: { var node = new BooleanNode(BooleanType.Or); context.AddChild(node); } break; case TokenType.Operator: { var node = new OperatorNode(token.Text); context.AddChild(node); } break; case TokenType.ParenthesisOpen: { var group = new ParenthesisGroupNode(); context.PushParent(group); } break; case TokenType.ParenthesisClose: { context.PopParent(); } break; case TokenType.Quote: // Quotes should have been removed by BuildSentences(). throw new Exception(); case TokenType.UnaryNot: { var node = new UnaryNode(UnaryType.Not); context.AddChild(node); } break; default: throw new NotImplementedException(); } } }