/*******************************************************************************
* Copyright (c) 2007, 2008 Edgar Espina.
* 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
*
*******************************************************************************/
package org.deved.antlride.railroad;
import java.awt.Dimension;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import net.hydromatic.clapham.chart.Chart;
import net.hydromatic.clapham.chart.ChartFactory;
import net.hydromatic.clapham.chart.ChartOptions;
import net.hydromatic.clapham.chart.draw2d.Draw2dChart;
import net.hydromatic.clapham.chart.exporter.ChartDocumentationProvider;
import net.hydromatic.clapham.chart.exporter.ChartExporterMonitor;
import net.hydromatic.clapham.chart.exporter.ChartHtmlExporter;
import net.hydromatic.clapham.graph.Grammar;
import net.hydromatic.clapham.graph.GrammarFactory;
import net.hydromatic.clapham.parser.ebnf.ANTLRLanguage;
import org.deved.antlride.core.model.IGrammar;
import org.deved.antlride.core.model.IRule;
import org.deved.antlride.core.util.AntlrTextHelper;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
public class RailRoadGenerator {
private static class AntlrDocumentationProvider implements
ChartDocumentationProvider {
private IGrammar grammar;
public AntlrDocumentationProvider(IGrammar grammar) {
this.grammar = grammar;
}
public String grammar(String grammarName) {
return AntlrTextHelper.parseDoc(grammar.getDocumentation());
}
public String rule(String ruleName) {
IRule rule = grammar.findRule(ruleName);
return rule != null ? AntlrTextHelper.parseDoc(rule
.getDocumentation()) : null;
}
}
private static class SWTChartExporterMonitor implements
ChartExporterMonitor {
private IProgressMonitor monitor;
public SWTChartExporterMonitor(IProgressMonitor monitor) {
this.monitor = monitor;
}
public void beginTask(String message, int totalOfWork) {
monitor.beginTask(message, totalOfWork);
}
public void done() {
monitor.done();
}
public void subTask(String message) {
monitor.subTask(message);
}
public void worked(int unit) {
monitor.worked(unit);
}
}
private static enum Draw2dChartFactory implements ChartFactory {
SINGLETON;
public Chart createChart(Grammar grammar) {
return new Draw2dChart(grammar);
}
}
private static class RailRoadDiagram extends Figure {
private Draw2dChart chart;
private String[] symbolNames;
public RailRoadDiagram(Draw2dChart chart, String[] symbolNames) {
this.symbolNames = symbolNames;
this.chart = chart;
}
@Override
protected void paintFigure(Graphics graphics) {
chart.setGraphics(graphics);
chart.prepare();
int w = 0;
int h = 0;
int initialX = chart.getOptions().initialX();
int initialY = chart.getOptions().initialY();
for (int i = 0; i < symbolNames.length; i++) {
Dimension size = chart.size(symbolNames[i]);
chart.draw(symbolNames[i]);
w = Math.max(w, size.width);
h = Math.max(h, size.height);
chart.getOptions().withInitialLocation(
initialX,
h + chart.getOptions().componentGapHeight()
+ chart.getOptions().symbolGapHeight());
}
// reset the original values
chart.getOptions().withInitialLocation(initialX, initialY);
setSize(w, h);
setPreferredSize(getSize());
}
}
private static String toEbnf(IRule[] rules) {
StringBuilder buff = new StringBuilder();
for (IRule rule : rules) {
buff.append(rule.toEbnf()).append("\n");
}
return buff.toString();
}
private static String[] names(IRule[] rules) {
String[] names = new String[rules.length];
for (int i = 0; i < rules.length; i++) {
names[i] = rules[i].getElementName();
}
return names;
}
public static IFigure generate(IRule[] rules, boolean optimize) {
Reader input = new StringReader(toEbnf(rules));
Grammar grammar = GrammarFactory.build(ANTLRLanguage.SINGLETON, input,
optimize);
return generate(grammar, rules, optimize, ChartOptions.INITIAL_X,
ChartOptions.INITIAL_Y);
}
private static IFigure generate(Grammar grammar, IRule[] rules,
boolean optimize, int x, int y) {
Draw2dChart chart = new Draw2dChart(grammar);
ChartOptions options = chart.createOptions();
options.withInitialLocation(x, y);
options.withSymbolName(rules.length > 1);
chart.setOptions(options);
return new RailRoadDiagram(chart, names(rules));
}
public void export(final IProgressMonitor monitor, IGrammar grammar,
RailRoadExportOptions options) throws IOException {
ChartDocumentationProvider documentationProvider = options
.includeDocumentation() ? new AntlrDocumentationProvider(
grammar) : null;
ChartHtmlExporter exporter = new ChartHtmlExporter(
Draw2dChartFactory.SINGLETON).withEbnfNotation(
options.includeTextualDefinition()).withOptimize(
options.optimized()).withOutputDirectory(
options.outputDirectory()).withDocumentationProvider(
documentationProvider);
exporter.export(new SWTChartExporterMonitor(monitor), grammar
.getElementName(), new StringReader(grammar.toEbnf()),
ANTLRLanguage.SINGLETON);
}
}