/* * Reference ETL Parser for Java * Copyright (c) 2000-2009 Constantine A Plotnikov * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package net.sf.etl.parsers.internal.term_parser.compiler; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import net.sf.etl.parsers.internal.term_parser.flattened.ContextView; import net.sf.etl.parsers.internal.term_parser.flattened.GrammarView; import net.sf.etl.parsers.internal.term_parser.states.StateMachinePeerFactory; /** * A builder for specific grammar. This class takes flattened * {@link GrammarView} of the grammar and builds an instance of * {@link StateMachinePeerFactory}. Translation is done in context of instance * of {@link GrammarAssemblyBuilder} class. * * @author const */ public class GrammarBuilder { /** assembly builder that is used to build an assembly of grammars */ private final GrammarAssemblyBuilder assemblyBuilder; /** a grammar view */ private final GrammarView grammarView; /** a peer factory that is being built */ private final StateMachinePeerFactory peerFactory = new StateMachinePeerFactory(); /** context builders */ private final HashMap<ContextView, ContextBuilder> contextBuilders = new HashMap<ContextView, ContextBuilder>(); /** * A constructor * * @param g * a grammar view to wrap * @param builder * an assembly builder */ public GrammarBuilder(GrammarAssemblyBuilder builder, GrammarView g) { super(); this.assemblyBuilder = builder; this.grammarView = g; } /** * This method identifies which activation factories should be created and * creates them. But it does not yet fill them with actual content. Because * it might require to reference other peer factories or activations in * them. */ void prepare() { // prepare contexts for (final ContextView view : grammarView.contexts()) { final ContextBuilder builder = new ContextBuilder(this, view); contextBuilders.put(view, builder); builder.prepare(); } // set dependencies to state machine builder. Set<String> deps = new HashSet<String>(); for (final GrammarView v : grammarView.getGrammarDependencies()) { final String systemId = v.getSystemId(); assert systemId != null : "System id should not be null. " + v.getPublicId(); deps.add(systemId); } deps = Collections.unmodifiableSet(deps); peerFactory.setDependencies(deps); } /** * @return Returns the assemblyBuilder. */ public GrammarAssemblyBuilder assemblyBuilder() { return assemblyBuilder; } /** * @return Returns the peerFactory. */ public StateMachinePeerFactory peerFactory() { return peerFactory; } /** * @return Returns the view. */ public GrammarView grammarView() { return grammarView; } /** * Build nodes for all contexts */ public void buildNodes() { for (final Iterator<ContextBuilder> i = contextBuilders.values() .iterator(); i.hasNext();) { final ContextBuilder builder = i.next(); builder.buildNodes(); } } /** * Build nodes for all contexts */ public void buildLookAhead() { for (final Iterator<ContextBuilder> i = contextBuilders.values() .iterator(); i.hasNext();) { final ContextBuilder builder = i.next(); builder.buildLookAhead(); } } /** * Build nodes for all contexts */ public void buildStateMachines() { for (final Iterator<ContextBuilder> i = contextBuilders.values() .iterator(); i.hasNext();) { final ContextBuilder builder = i.next(); builder.buildStateMachines(); } } /** * Find context builder for corresponding context view. Note that context * might come from other grammar. * * @param contextView * a context view for which context builder is searched. * @return a context builder for corresponding context view */ public ContextBuilder contextBuilder(ContextView contextView) { GrammarBuilder b; if (contextView.grammar() == grammarView) { b = this; } else { b = assemblyBuilder.grammarBuilder(contextView.grammar()); } return b.contextBuilders.get(contextView); } /** * @return logical name of grammar */ public String grammarName() { return grammarView.grammarName(); } }