blob: f7c29a7359c09a1ac169af1c24dc07dc1b221d6e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2006 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.gymnast.generator.core.generator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import org.eclipse.gymnast.generator.core.ast.AltRule;
import org.eclipse.gymnast.generator.core.ast.Alts;
import org.eclipse.gymnast.generator.core.ast.GymnastASTNodeVisitor;
import org.eclipse.gymnast.generator.core.ast.HeaderSection;
import org.eclipse.gymnast.generator.core.ast.Option;
import org.eclipse.gymnast.generator.core.ast.Rule;
import org.eclipse.gymnast.generator.core.ast.SimpleExpr;
import org.eclipse.gymnast.runtime.core.ast.ASTNode;
/**
* @author cjdaly@us.ibm.com
*
*/
public class GrammarInfo extends GymnastASTNodeVisitor implements IGrammarInfo {
private GeneratorContext _context;
private GeneratorUtil _util;
private String _languageName;
private Hashtable _options = new Hashtable();
private ArrayList _rules = new ArrayList();
private Hashtable _ruleNameToRule = new Hashtable();
private Hashtable _ruleToRuleRefCollector = new Hashtable();
// key is rule name
// value is ArrayList of altRule names that reference the rule in an alt
private Hashtable _altReverseMap = new Hashtable();
private String _entryRuleName = "compUnit";
private String _entryRuleClassName = "CompUnit";
private Rule _currentRule;
public GrammarInfo(GeneratorContext context) {
_context = context;
_util = _context.getUtil();
init();
}
private void init() {
visit(_context.getCompUnit());
for (int i = 0; i < _rules.size(); i++) {
Rule rule = (Rule)_rules.get(i);
initRuleParams(rule);
if (ASTUtil.hasAttr(rule, "entry")) {
_entryRuleName = getRuleName(rule);
_entryRuleClassName = getTypeName(rule);
}
}
}
private void initRuleParams(Rule rule) {
RuleRefCollector refs = getRuleRefCollector(rule);
String[] altReferencers = getAltReferencers(ASTUtil.getName(rule));
for (int i = 0; i < altReferencers.length; i++) {
String altReferencerName = altReferencers[i];
Rule altRule = getRule(altReferencerName);
RuleRefCollector altRuleRefs = getRuleRefCollector(altRule);
String[] labels = altRuleRefs.getLabels();
for (int j = 0; j < labels.length; j++) {
String label = labels[j];
if (altRuleRefs.isAltSeq(label)) {
refs.addInherited(label, altRuleRefs.getType(label));
}
}
}
}
public String getLanguageName() {
return _languageName;
}
public String getEntryRuleName() {
return _entryRuleName;
}
public String getEntryRuleClassName() {
return _entryRuleClassName;
}
public Rule[] getRules() {
return (Rule[]) _rules.toArray(new Rule[_rules.size()]);
}
public Rule getRule(String name) {
return (Rule)_ruleNameToRule.get(name);
}
public String getRuleName(Rule rule) {
return ASTUtil.getName(rule);
}
public String getTypeName(Rule rule) {
return _util.toUppercaseName(getRuleName(rule));
}
public String getOptionValue(String name) {
if (!_options.containsKey(name)) return null;
String value = (String)_options.get(name);
value = Util.removeSurroundingQuotes(value);
return value;
}
public RuleRefCollector getRuleRefCollector(Rule rule) {
return (RuleRefCollector)_ruleToRuleRefCollector.get(rule);
}
public String[] getAltReferencers(String ruleName) {
if (_altReverseMap.containsKey(ruleName)) {
ArrayList altList = (ArrayList)_altReverseMap.get(ruleName);
return (String[]) altList.toArray(new String[altList.size()]);
}
return new String[]{};
}
public String[] getLiterals() {
final HashSet literals = new HashSet();
new GymnastASTNodeVisitor() {
public boolean beginVisit(SimpleExpr simpleExpr) {
String value = simpleExpr.getValue().getText();
if (value.startsWith("\"")) {
literals.add(Util.removeSurroundingQuotes(value));
}
return false;
}
}.visit(_context.getCompUnit());
return (String[]) literals.toArray(new String[literals.size()]);
}
public boolean beginVisit(HeaderSection headerSection) {
_languageName = headerSection.getName().getText();
_util.report("language: " + getLanguageName());
return true;
}
public boolean beginVisit(Option option) {
String name = option.getName().getText();
String value = option.getValue().getText();
_options.put(name, value);
_util.report("option " + name + " = " + value);
return false;
}
public boolean beginVisit(Rule rule) {
String name = ASTUtil.getName(rule);
if (_ruleNameToRule.containsKey(name)) {
throw new RuntimeException("Rule " + name + "declared twice!");
}
_util.report("rule: " + name);
_currentRule = rule;
_rules.add(rule);
_ruleNameToRule.put(name, rule);
RuleRefCollector ruleRefs = new RuleRefCollector(rule, _context);
_ruleToRuleRefCollector.put(rule, ruleRefs);
return true;
}
public boolean beginVisit(Alts alts) {
if (_currentRule instanceof AltRule) {
for (int i = 0; i < alts.getChildCount(); i++) {
ASTNode child = alts.getChild(i);
if (child instanceof SimpleExpr) {
SimpleExpr se = (SimpleExpr)child;
String refRuleName = se.getValue().getText();
ArrayList altList = null;
if (!_altReverseMap.containsKey(refRuleName)) {
altList = new ArrayList();
_altReverseMap.put(refRuleName, altList);
}
else {
altList = (ArrayList)_altReverseMap.get(refRuleName);
}
altList.add(ASTUtil.getName(_currentRule));
}
}
}
return false;
}
}