Added support for a new EDD format, as well as support for the EDD being defined...
[DTRules.git] / DSLCompiler / src / main / java / com / dtrules / compiler / cup / Compiler.java
blob5cf872e81dd6de670179973ae69ca1d31f0d65da
1 /*
2 * Copyright 2004-2007 MTBJ, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.dtrules.compiler.cup;
18 import java.io.ByteArrayInputStream;
19 import java.io.DataInputStream;
20 import java.io.InputStream;
21 import java.io.PrintStream;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import com.dtrules.compiler.RType;
26 import com.dtrules.entity.REntity;
27 import com.dtrules.entity.REntityEntry;
28 import com.dtrules.infrastructure.RulesException;
29 import com.dtrules.interpreter.IRObject;
30 import com.dtrules.interpreter.RName;
31 import com.dtrules.session.EntityFactory;
32 import com.dtrules.session.ICompiler;
33 import com.dtrules.session.IRSession;
35 public class Compiler implements ICompiler {
37 private HashMap<RName,RType> types = null;
38 private final EntityFactory ef;
39 private final IRSession session;
41 private int localcnt = 0; // Count of local variables
42 HashMap<String,RLocalType> localtypes = new HashMap<String,RLocalType>();
44 public void setTableName(String tablename) {
49 /**
50 * Add a identifier and type to the types HashMap.
51 * @param entity
52 * @param name
53 * @param itype
54 * @throws Exception
56 private void addType( REntity entity, RName name, int itype) throws Exception {
57 RType type = types.get(name);
58 if(type==null){
59 type = new RType(name,itype,entity);
60 types.put(name,type);
61 }else{
62 if(type.getType()!=itype){
63 String entitylist = entity.getName().stringValue();
64 for(int i=0; i<type.getEntities().size(); i++){
65 entitylist += " "+type.getEntities().get(i).getName().stringValue();
67 throw new Exception("Conflicting types for attribute "+name+" on "+entitylist);
69 type.addEntityAttribute(entity);
73 /**
74 * Get all the types out of the Entity Factory and make them
75 * available to the compiler.
76 * @param ef
77 * @return
78 * @throws Exception
80 public HashMap<RName,RType> getTypes(EntityFactory ef) throws Exception {
82 if(types!=null)return types;
84 types = new HashMap<RName, RType>();
85 Iterator<RName> entities = ef.getEntityRNameIterator();
86 while(entities.hasNext()){
87 RName name = entities.next();
88 REntity entity = ef.findRefEntity(name);
89 Iterator<RName> attribs = entity.getAttributeIterator();
90 addType(entity,entity.getName(),IRObject.iEntity);
91 while(attribs.hasNext()){
92 RName attribname = attribs.next();
93 REntityEntry entry = entity.getEntry(attribname);
94 addType(entity,attribname,entry.type);
98 Iterator<RName> tables = ef.getDecisionTableRNameIterator();
99 while(tables.hasNext()){
100 RName tablename = tables.next();
101 RType type = new RType(tablename,IRObject.iDecisiontable,(REntity) ef.getDecisiontables());
102 if(types.containsKey(tablename)){
103 System.out.println("Multiple Decision Tables found with the name '"+types.get(tablename)+"'");
105 types.put(tablename, type);
108 return types;
112 * Prints all the types known to the compiler
114 public void printTypes(PrintStream out) throws RulesException {
115 Object typenames[] = types.keySet().toArray();
116 for(int i=0;i<typenames.length-1;i++){
117 for(int j=0;j<typenames.length-1;j++){
118 RName one = (RName)typenames[j], two = (RName)typenames[j+1];
119 if(one.compare(two)>0){
120 Object hold = typenames[j];
121 typenames[j]=typenames[j+1];
122 typenames[j+1]=hold;
126 for(int i=0;i<typenames.length-1;i++){
127 for(int j=0;j<typenames.length-1;j++){
128 RName one = (RName)typenames[j], two = (RName)typenames[j+1];
129 if(types.get(one).getType()> types.get(two).getType()){
130 Object hold = typenames[j];
131 typenames[j]=typenames[j+1];
132 typenames[j+1]=hold;
136 for(int i=0;i<typenames.length; i++){
137 out.println(types.get(typenames[i]));
143 private TokenFilter tfilter;
145 public ArrayList<String> getParsedTokens(){
146 return tfilter.getParsedTokens();
149 public void newDecisionTable () {
150 localcnt = 0;
151 localtypes.clear();
155 * The actual routine to compile either an action or condition. The code
156 * is all the same, only a flag is needed to decide to compile an action vs
157 * condition.
158 * @param action Flag
159 * @param s String to compile
160 * @return Postfix
161 * @throws Exception Throws an Exception on any error.
163 private String compile (boolean action, String s)throws Exception {
166 InputStream stream = new ByteArrayInputStream(s.getBytes());
167 DataInputStream input = new DataInputStream(stream);
168 DTRulesscanner lexer = new DTRulesscanner (input);
169 tfilter = new TokenFilter(session, lexer,types, localtypes);
170 DTRulesParser parser = new DTRulesParser(tfilter);
171 Object result = null;
173 parser.localCnt = localcnt;
174 try {
175 result = parser.parse().value;
176 }catch(Exception e){
177 throw new Exception( "Error found at Line:Char ="+lexer.linenumber()+":"+lexer.charnumber()+" "+
178 e.toString());
180 localcnt = parser.localCnt;
181 localtypes.putAll(parser.localtypes);
182 return result.toString();
185 /* (non-Javadoc)
186 * @see com.dtrules.compiler.ICompiler#getLastPreFixExp()
188 public String getLastPreFixExp(){
189 return "";
193 * Build a compiler instance. This compiler compiles either a condition or
194 * an action. Use the compiler access methods to compile each.
196 * @param entityfactory Needed to generate the symbol table used by the compiler.
197 * @throws Exception Throws an exception of a compiler error is encountered.
199 public Compiler(IRSession session) throws Exception {
200 this.session = session;
201 ef = session.getEntityFactory();
202 getTypes(ef);
206 /* (non-Javadoc)
207 * @see com.dtrules.compiler.ICompiler#compileContext(java.lang.String)
209 public String compileContext(String context) throws Exception {
210 return compile(true,"context "+context);
213 /* (non-Javadoc)
214 * @see com.dtrules.compiler.ICompiler#compileAction(java.lang.String)
216 public String compileAction(String action) throws Exception {
217 return compile(true,"action "+action);
219 /* (non-Javadoc)
220 * @see com.dtrules.compiler.ICompiler#compileCondition(java.lang.String)
222 public String compileCondition(String condition) throws Exception {
223 return compile(false,"condition "+ condition);
225 /* (non-Javadoc)
226 * @see com.dtrules.compiler.ICompiler#getTypes()
228 public HashMap<RName,RType> getTypes() {
229 return types;
232 * Return the list of Possibly (but we can't tell for sure) referenced attributes
233 * so far by this compiler.
235 public ArrayList<String> getPossibleReferenced() {
236 ArrayList<String> v = new ArrayList<String>();
237 for(RType type :types.values()){
238 v.addAll(type.getPossibleReferenced());
240 return v;
243 * Return the list of UnReferenced attributes so far by this compiler
245 public ArrayList<String> getUnReferenced() {
246 ArrayList<String> v = new ArrayList<String>();
247 for(RType type :types.values()){
248 v.addAll(type.getUnReferenced());
250 return v;