/*
* 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();
}
}