]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/units/internal/parser/UnitParser.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / units / internal / parser / UnitParser.java
1 /*******************************************************************************
2  *  Copyright (c) 2010 Association for Decentralized Information Management in
3  *  Industry THTH ry.
4  *  All rights reserved. This program and the accompanying materials
5  *  are made available under the terms of the Eclipse Public License v1.0
6  *  which accompanies this distribution, and is available at
7  *  http://www.eclipse.org/legal/epl-v10.html
8  *
9  *  Contributors:
10  *      VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.databoard.units.internal.parser;
13
14 import org.simantics.databoard.units.internal.UnitParseException;
15
16 public abstract class UnitParser {
17
18         String string;
19         int pos;
20         
21         int nextChar;
22         int sign;
23         
24         public UnitParser() {
25         }
26
27         void next() {
28                 ++pos;
29                 if(pos >= string.length())
30                         nextChar = -1;
31                 else
32                         nextChar = string.charAt(pos);
33         }
34         
35         public void unit(String string, int sign) throws UnitParseException {
36                 this.string = string;
37                 this.pos = -1;
38                 this.sign = sign;
39                 next();
40                 
41                 expression();
42                 expect(-1);
43         }
44         
45         /* Grammar
46          * 
47          * unit_expression: unit_numerator [ "/" unit_denominator ]
48          * unit_numerator: "1" | unit_factors | "(" unit_expression ")"
49          * unit_denominator: unit_factor | "(" unit_expression ")"
50          * unit_factors: unit_factor [ "." unit_factors ]
51          * unit_factor: unit_operand [ unit_exponent ]
52          * unit_exponent: [ "+" | "-" ] integer
53          * unit_operand: unit_symbol | unit_prefix unit_symbol 
54          */
55         
56         void expression() throws UnitParseException {
57                 numerator();
58                 if(nextChar == '/') {
59                         next();
60                         denominator();
61                 }               
62         }
63         
64         void numerator() throws UnitParseException {
65                 if(nextChar == '1')
66                         next();
67                 else if(nextChar == '(') {
68                         next();
69                         expression();
70                         skip(')');
71                 }
72                 else
73                         factors();
74         }
75
76         void denominator() throws UnitParseException {
77                 sign = -sign;
78                 if(nextChar == '(') {
79                         next();
80                         expression();
81                         skip(')');
82                 }
83                 else
84                         factor();
85                 sign = -sign;
86         }
87         
88         void factors() throws UnitParseException {
89                 while(true) {
90                         factor();
91                         if(nextChar == '.')
92                                 next();
93                         else
94                             break;
95                 }
96         }
97         
98         void factor() throws UnitParseException {
99                 // Base
100                 int factorBegin = pos;
101                 while((nextChar >= 'a' && nextChar <= 'z') || (nextChar >= 'A' && nextChar <= 'Z') || (nextChar=='ยต') || nextChar=='(' || nextChar==')' || nextChar=='%') 
102                         next();
103                 int exponentBegin = pos;
104                 if(factorBegin == exponentBegin)
105                         throw new UnitParseException(string, 
106                                         "Expected base unit name, but got " + charName(nextChar) + " at position " + pos + ".");        
107                 String baseUnit = string.substring(factorBegin, exponentBegin);
108                 
109                 // Exponent
110                 if(nextChar == '-' || nextChar == '+' || (nextChar >= '0' && nextChar <= '9')) {
111                         next();
112                         while(nextChar >= '0' && nextChar <= '9')
113                                 next();
114                 }
115                 int exponentEnd = pos;
116                 if(exponentEnd > exponentBegin) {
117                         String exponentString = string.substring(exponentBegin, exponentEnd);
118                         try {
119                                 visit(baseUnit, sign * Integer.parseInt(exponentString));
120                         } catch(NumberFormatException e) {
121                                 throw new UnitParseException(string, 
122                                                 "Invalid exponent \"" + exponentString + "\" at position " + pos + ".");        
123                         }
124                 }
125                 else
126                         visit(baseUnit, sign);
127         }
128                         
129         private void skip(char c) throws UnitParseException {
130                 expect(c);                      
131                 next();
132         }
133         
134         private static String charName(int c) {
135                 if(c >= 0)
136                         return "'" + Character.toString((char)c) + "'";
137                 else
138                         return "end of unit";
139         }
140         
141         private void expect(int c) throws UnitParseException {
142                 if(nextChar != c)
143                         throw new UnitParseException(string, 
144                                         "Expected " + charName(c) + ", but got " + charName(nextChar) + " at position " + pos + ".");   
145         }
146         
147         public abstract void visit(String baseUnit, int exponent);
148         
149 }