Home | History | Annotate | Download | only in parser
      1 /*******************************************************************************
      2  * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors
      3  * All rights reserved. This program and the accompanying materials
      4  * are made available under the terms of the Eclipse Public License v1.0
      5  * which accompanies this distribution, and is available at
      6  * http://www.eclipse.org/legal/epl-v10.html
      7  *
      8  * Contributors:
      9  *    Marc R. Hoffmann - initial API and implementation
     10  *
     11  *******************************************************************************/
     12 package org.jacoco.examples.parser;
     13 
     14 import static java.io.StreamTokenizer.TT_EOF;
     15 import static java.io.StreamTokenizer.TT_NUMBER;
     16 
     17 import java.io.IOException;
     18 import java.io.StreamTokenizer;
     19 import java.io.StringReader;
     20 
     21 import org.jacoco.examples.expressions.Add;
     22 import org.jacoco.examples.expressions.Const;
     23 import org.jacoco.examples.expressions.Div;
     24 import org.jacoco.examples.expressions.IExpression;
     25 import org.jacoco.examples.expressions.Mul;
     26 import org.jacoco.examples.expressions.Sub;
     27 
     28 public class ExpressionParser {
     29 
     30 	private final StreamTokenizer tokenizer;
     31 
     32 	public ExpressionParser(final String s) throws IOException {
     33 		tokenizer = new StreamTokenizer(new StringReader(s));
     34 		tokenizer.ordinaryChar('(');
     35 		tokenizer.ordinaryChar(')');
     36 		tokenizer.ordinaryChar('+');
     37 		tokenizer.ordinaryChar('-');
     38 		tokenizer.ordinaryChar('*');
     39 		tokenizer.ordinaryChar('/');
     40 	}
     41 
     42 	public IExpression parse() throws IOException {
     43 		tokenizer.nextToken();
     44 		final IExpression e = term();
     45 		expect(TT_EOF);
     46 		return e;
     47 	}
     48 
     49 	private IExpression term() throws IOException {
     50 		IExpression e = product();
     51 		while (true) {
     52 			if (accept('+')) {
     53 				e = new Add(e, product());
     54 			} else if (accept('-')) {
     55 				e = new Sub(e, product());
     56 			} else {
     57 				return e;
     58 			}
     59 		}
     60 	}
     61 
     62 	private IExpression product() throws IOException {
     63 		IExpression e = factor();
     64 		while (true) {
     65 			if (accept('*')) {
     66 				e = new Mul(e, factor());
     67 			} else if (accept('/')) {
     68 				e = new Div(e, factor());
     69 			} else {
     70 				return e;
     71 			}
     72 		}
     73 	}
     74 
     75 	private IExpression factor() throws IOException {
     76 		final IExpression e;
     77 		if (accept('(')) {
     78 			e = term();
     79 			expect(')');
     80 		} else {
     81 			expect(TT_NUMBER);
     82 			e = new Const(tokenizer.nval);
     83 		}
     84 		return e;
     85 	}
     86 
     87 	private boolean accept(final int type) throws IOException {
     88 		if (tokenizer.ttype == type) {
     89 			tokenizer.nextToken();
     90 			return true;
     91 		}
     92 		return false;
     93 	}
     94 
     95 	private void expect(final int type) throws IOException {
     96 		if (tokenizer.ttype != type) {
     97 			throw new IOException("Invalid Syntax.");
     98 		}
     99 		tokenizer.nextToken();
    100 	}
    101 
    102 }
    103