org.modelcc.parser.fence.ParsedGraph Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ModelCC Show documentation
Show all versions of ModelCC Show documentation
ModelCC is a model-based parser generator (a.k.a. compiler compiler) that decouples language specification from language processing, avoiding some of the problems caused by grammar-driven parser generators. ModelCC receives a conceptual model as input, along with constraints that annotate it. It is then able to create a parser for the desired textual language and the generated parser fully automates the instantiation of the language conceptual model. ModelCC also includes a built-in reference resolution mechanism that results in abstract syntax graphs, rather than mere abstract syntax trees.
The newest version!
/*
* ModelCC, distributed under ModelCC Shared Software License, www.modelcc.org
*/
package org.modelcc.parser.fence;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.modelcc.language.syntax.Grammar;
import org.modelcc.language.syntax.InputSymbol;
import org.modelcc.lexer.LexicalGraph;
/**
* Parse Graph.
* A concrete syntax tree or parse tree or parsing tree or derivation tree is
* an ordered, rooted tree that represents the syntactic structure of a string
* according to some context-free grammar.
*
* @author Luis Quesada ([email protected]), refactored by Fernando Berzal ([email protected])
*/
public final class ParsedGraph implements Serializable
{
/**
* Lexical graph
*/
private LexicalGraph lg;
/**
* Grammar.
*/
private Grammar grammar;
/**
* Set of symbols used in this graph.
*/
private Set symbols;
/**
* Set of start symbols of this graph.
*/
private Set start;
/**
* List of preceding symbols.
*/
private Map> preceding;
/**
* List of following symbols.
*/
private Map> following;
/**
* Start positions
*/
private Map> startPositions;
/**
* End positions
*/
private Map> endPositions;
/**
* Constructor.
* @param grammar Language grammar
* @param lg Lexical graph
*/
public ParsedGraph (Grammar grammar, LexicalGraph lg)
{
this.lg = lg;
this.grammar = grammar;
this.symbols = new HashSet();
this.start = new HashSet();;
this.preceding = new HashMap>();
this.following = new HashMap>();
this.startPositions = new HashMap>();
this.endPositions = new HashMap>();
}
// Language grammar
public Grammar getGrammar()
{
return grammar;
}
// Lexical graph
public LexicalGraph getLexicalGraph ()
{
return lg;
}
// Symbols in the graph
public Set getSymbols()
{
return Collections.unmodifiableSet(symbols);
}
public void addSymbol (ParsedSymbol s)
{
symbols.add(s);
// Start/end position
Set aux;
int i;
i = s.getStartIndex();
aux = startPositions.get(i);
if (aux == null) {
aux = new HashSet();
startPositions.put(i,aux);
}
aux.add(s);
i = s.getEndIndex();
aux = endPositions.get(i);
if (aux == null) {
aux = new HashSet();
endPositions.put(i,aux);
}
aux.add(s);
}
public boolean contains (InputSymbol s)
{
return symbols.contains(s);
}
// Start symbols
public Set getStart()
{
return Collections.unmodifiableSet(start);
}
public void addStart (ParsedSymbol s)
{
start.add(s);
}
// Preceding/following relationships
protected Map> getPreceding()
{
return Collections.unmodifiableMap(preceding);
}
public Set getPreceding (InputSymbol s)
{
return preceding.get(s);
}
protected Map> getFollowing()
{
return Collections.unmodifiableMap(following);
}
public Set getFollowing (InputSymbol s)
{
return following.get(s);
}
// Start/end positions
public Set getSymbolsStartingAt(int position)
{
return startPositions.get(position);
}
public Set getSymbolsEndingAt (int position)
{
return endPositions.get(position);
}
// Preceding/following symbols
/**
* Add a parsed symbol to the set of another parsed symbol.
* @param t1 the parsed symbol.
* @param t2 the parsed symbol to be added.
*/
private void addMapElement(Map> target,ParsedSymbol t1,ParsedSymbol t2)
{
Set set = target.get(t1);
if (set == null) {
set = new HashSet();
target.put(t1,set);
}
set.add(t2);
}
/**
* Remove a parsed symbol from the set of another parsed symbol.
* @param t1 the parsed symbol.
* @param t2 the parsed symbol to be removed.
*/
private void removeMapElement(Map> target,InputSymbol t1,InputSymbol t2)
{
Set set = target.get(t1);
if (set == null) {
return;
}
set.remove(t2);
if (set.isEmpty())
target.remove(t1);
}
/**
* Adds a preceding/following relationship between parsed symbols t1 and t2.
* @param t1 the preceding parsed symbol.
* @param t2 the following parsed symbol.
*/
public void addLink (ParsedSymbol t1,ParsedSymbol t2)
{
addMapElement(preceding,t2,t1);
addMapElement(following,t1,t2);
}
/**
* Removes a preceding/following relationship between parsed symbols t1 and t2.
* @param t1 the preceding parsed symbol.
* @param t2 the following parsed symbol.
*/
public void removeLink (InputSymbol t1,InputSymbol t2)
{
removeMapElement(preceding,t2,t1);
removeMapElement(following,t1,t2);
}
}