/* * Copyright 2013 Hewlett-Packard Development Company, L.P * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hp.alm.ali.idea.translate.expr; public class ExpressionParser { public static Node parse(String expr) { Lexer lexer = new Lexer(expr); return matchExpr(lexer); } private static Node matchExpr(Lexer lexer) { Node result = matchE(lexer); if(lexer.next().type != Type.END) { throw new ParserException("Trailing characters", lexer.next().start); } return result; } private static Node matchE(Lexer lexer) { Node result = matchT(lexer); if(lexer.next().type == Type.AND || lexer.next().type == Type.OR) { Lexeme lexeme = lexer.consume(); Node right = matchE(lexer); if(!right.bound && (right.type == Type.AND || right.type == Type.OR)) { return new Node(right.type, new Node(lexeme.type, result, right.left), right.right); } else { return new Node(lexeme.type, result, right); } } return result; } private static Node matchT(Lexer lexer) { if(lexer.next().type == Type.NOT) { Lexeme lexeme = lexer.consume(); return new Node(lexeme.type, matchT(lexer)); } return matchQ(lexer); } private static Node matchQ(Lexer lexer) { Lexeme next = lexer.next(); switch (next.type) { case EQ: case LT: case LTE: case GT: case GTE: case DIFFERS: lexer.consume(); return new Node(next.type, matchV(lexer)); } return matchF(lexer); } private static Node matchF(Lexer lexer) { if(lexer.next().type == Type.LEFT_P) { lexer.consume(); Node result = matchE(lexer); result.bound = true; lexer.expect(Type.RIGHT_P); return result; } return matchV(lexer); } private static Node matchV(Lexer lexer) { Lexeme lexeme = lexer.consume(); if(lexeme.type == Type.VALUE) { return new Node(lexeme.value); } throw new ParserException("Expected VALUE", lexeme.start); } }