/** | |
* Copyright (c) 2008 INRIA. | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/epl-v10.html | |
* | |
* Contributors: | |
* INRIA - initial API and implementation | |
* | |
* $Id: ParserLauncher.java,v 1.3 2008/06/28 17:12:25 fjouault Exp $ | |
*/ | |
package org.eclipse.gmt.tcs.injector; | |
import java.io.InputStream; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.Iterator; | |
import java.util.List; | |
import java.util.Map; | |
import org.eclipse.gmt.tcs.injector.TCSRuntime.RefSetting; | |
import org.eclipse.gmt.tcs.injector.wrappers.ParserWrapper; | |
/** | |
* | |
* @author Mikaël Barbero | |
* @author Frédéric Jouault | |
* | |
*/ | |
public class ParserLauncher { | |
private final static int DEFAULT_TAB_SIZE = 8; | |
private List refSettings; | |
private ParserWrapper parserWrapper; | |
public Object parse(ModelAdapter target, InputStream in, Map arguments) { | |
Object ret = null; | |
refSettings = new ArrayList(); | |
int tabSize = arguments.get("tabSize") == null ? DEFAULT_TAB_SIZE : Integer.parseInt((String)arguments.get("tabSize")); | |
String parserGeneratorClassName = (String)arguments.get("parserGenerator"); | |
if(parserGeneratorClassName != null) { | |
try { | |
parserWrapper = (ParserWrapper)Class.forName("org.eclipse.gmt.tcs.injector.wrappers." + parserGeneratorClassName + ".ParserWrapper", true, Thread.currentThread().getContextClassLoader()).newInstance(); | |
} catch (InstantiationException e) { | |
throw new IllegalArgumentException("Unable to instanciate parser generator with name " + parserGeneratorClassName, e); | |
} catch (IllegalAccessException e) { | |
throw new IllegalArgumentException("Unable to access to parser generator with name " + parserGeneratorClassName, e); | |
} catch (ClassNotFoundException e) { | |
throw new IllegalArgumentException("Unable to locate parser generator with name " + parserGeneratorClassName, e); | |
} | |
} else { | |
// default parser generator | |
parserWrapper = new org.eclipse.gmt.tcs.injector.wrappers.antlr3.ParserWrapper(); | |
} | |
String nameAndProductionRule = (String)arguments.get("name"); | |
String ss[] = nameAndProductionRule.split("-"); | |
String name = ss[0]; | |
String productionRule = "main"; | |
if(ss.length > 1) { | |
productionRule = ss[1]; | |
} | |
TCSRuntime runtime = new TCSRuntime(target, parserWrapper, refSettings, arguments); | |
parserWrapper.setRuntime(runtime); | |
try { | |
ret = parserWrapper.parse(tabSize, name, productionRule, in, arguments); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
// if(runtime.getNbErrors() == 0) { | |
// A RefSetting that can autoCreate an element should come before other | |
// RefSettings that might refer to this element. | |
Collections.sort(refSettings, new Comparator() { | |
public int compare(Object o1, Object o2) { | |
RefSetting rs1 = (RefSetting)o1; | |
RefSetting rs2 = (RefSetting)o2; | |
if(rs1.canAutoCreate() && !rs2.canAutoCreate()) | |
return -1; // autoCreate first | |
else if(rs2.canAutoCreate() && !rs1.canAutoCreate()) | |
return 1; // autoCreate first | |
else // both or none are autoCreate | |
return 0; // don't care | |
} | |
}); | |
// A RefSetting that relies on imported contexts can only be executed after | |
// the RefSetting importing the corresponding context (and this, recursively). | |
// For now, we sort RefSettings so that all those that import a context | |
// are executed first. | |
// If a RefSetting that imports a context relies on imported contexts, | |
// then this solution is not enough. | |
// The concept of imported context should be defined cleanly first. | |
Collections.sort(refSettings, new Comparator() { | |
public int compare(Object o1, Object o2) { | |
RefSetting rs1 = (RefSetting)o1; | |
RefSetting rs2 = (RefSetting)o2; | |
if(rs1.importContext && !rs2.importContext) | |
return -1; // importContext first | |
else if(rs2.importContext && !rs1.importContext) | |
return 1; // importContext first | |
else // both or none are importContext | |
return 0; // don't care | |
} | |
}); | |
for(Iterator i = refSettings.iterator() ; i.hasNext() ; ) { | |
RefSetting rs = (RefSetting)i.next(); | |
try { | |
rs.doIt(); | |
} catch(Exception e) { | |
System.out.println("Warning: one refSetting crashed:"); | |
e.printStackTrace(System.out); | |
} | |
} | |
// } | |
return ret; | |
} | |
} |