/* * GFCMModules.java * Copyright (C) 2004-2005, Bjorn Bringert (bringert@cs.chalmers.se) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package se.chalmers.cs.gf.gfcutil; import se.chalmers.cs.gf.GFC.*; import se.chalmers.cs.gf.GFC.Absyn.*; import se.chalmers.cs.gf.GFException; import se.chalmers.cs.gf.util.*; import java.util.*; import java.io.*; /** * Contains a collection of GFC modules which share an abstract syntax. */ public class GFCMModules { /** * Maps module names to modules. */ private Map map; /** * The name of the main abstract module. */ private String mainAbstract; /** * The names of the main concrete modules. */ private List mainConcrete; public GFCMModules(Canon gfc) { this.map = new TreeMap(); this.mainAbstract = null; this.mainConcrete = new LinkedList(); // FIXME: the Canon visitor is broken because of a name clash, // that's why we do type case here. if (gfc instanceof Gr) { Gr gr = (Gr)gfc; for (Module m : gr.listmodule_) add(new GFCModule((Mod)m, map)); // Set main abstract module to first abstract module for (GFCModule gm : map.values()) { if (gm.getType() == ModuleType.ABSTRACT) { mainAbstract = gm.getName(); break; } } // Set main concrete modules to all concrete modules // for the main abstract module for (GFCModule m : map.values()) { if (m.getType() == ModuleType.CONCRETE && m.getAbstract().equals(mainAbstract)) mainConcrete.add(m.getName()); } } else { MGr mgr = (MGr)gfc; for (Module m : mgr.listmodule_) add(new GFCModule((Mod)m, map)); // Set main abstract module from header mainAbstract = mgr.ident_; // Set main concrete modules from header for (String m : mgr.listident_) mainConcrete.add(m); } } /** * Gets a module by name. */ public GFCModule getModule(String name) { return map.get(name); } /** * Gets the main abstract module. */ public GFCModule getMainAbstractModule() { return getModule(mainAbstract); } /** * Gets the main concrete modules, i.e. those that are concrete syntaxes * for the main abstract module. */ public List getMainConcreteModules() { List l = new ArrayList(mainConcrete.size()); for (String n : mainConcrete) l.add(getModule(n)); return l; } /** * Add a GFCModule to this collection of modules. */ private void add(GFCModule module) { String name = module.getName(); if (map.containsKey(name)) throw new GFException("Module " + name + " already exists."); map.put(name, module); } /** * Load a GFCM grammar from a file. * * @param file Filename. */ public static GFCMModules loadGFCM(String file) throws FileNotFoundException, IOException { return loadGFCM(FileUtil.openFile(file)); } /** * Load a GFCM grammar from a Reader. */ public static GFCMModules loadGFCM(Reader input) throws IOException { // System.err.println("Parsing GFCM file"); Canon gfc = GFCParser.parseCanon(input); // System.err.println("Done parsing GFCM file"); input.close(); return new GFCMModules(gfc); } /** * Load a gzipped GFCM grammar from a file. */ /* public static GFCMModules loadGFCM_GZ(String file) throws FileNotFoundException, IOException { return loadGFCM(new java.util.zip.GZIPInputStream(new FileInputStream(file))); } */ }