org.modelcc.language.lexis.LexicalSpecificationFactory 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.language.lexis;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.modelcc.language.CyclicPrecedenceException;
import org.modelcc.language.metamodel.LanguageModel;
/**
* Lexical specification factory.
*
* @author Luis Quesada ([email protected]) & Fernando Berzal ([email protected])
*/
public final class LexicalSpecificationFactory implements Serializable
{
private LexicalSpecification lexis;
/**
* Default constructor.
*/
public LexicalSpecificationFactory()
{
lexis = new LexicalSpecification();
}
/**
* Add token specification.
* @param ts the token specification to be added.
*/
public void addTokenSpecification(TokenSpecification ts)
{
if (ts != null)
lexis.addTokenSpecification(ts);
}
/**
* Skip token specification.
* @param ts the token specification to be skipped.
*/
public void skipTokenSpecification(TokenSpecification ts)
{
if (ts != null)
lexis.skipTokenSpecification(ts);
}
/**
* Removes a token specification.
* @param ts the token specification to remove.
*/
public void removeTokenSpecification(TokenSpecification ts)
{
if (ts!=null)
lexis.removeTokenSpecification(ts);
}
/**
* Adds a precedence relationship between tokens.
* @param ts1 the token that precedes.
* @param ts2 the token that is preceded.
*/
public void addPrecedence (TokenSpecification ts1,TokenSpecification ts2)
{
lexis.addPrecedence(ts1, ts2);
}
/**
* Removes a precedence relationship between tokens.
* @param ts1 the token that precedes.
* @param ts2 the token that is preceded.
*/
public void removePrecedence(TokenSpecification ts1,TokenSpecification ts2)
{
lexis.removePrecedence(ts1, ts2);
}
/**
* Create a lexical specification.
* @throws CyclicTokenPrecedenceException
* @return the lexical specification.
*/
public LexicalSpecification create()
throws CyclicPrecedenceException
{
return create(null);
}
/**
* Create a lexical specification
* @param model
* @return
* @throws CyclicPrecedenceException
*/
public LexicalSpecification create(LanguageModel model)
throws CyclicPrecedenceException
{
Set pool = new HashSet();
pool.addAll(lexis.getTokenSpecifications());
Set preceded;
List tokens = new ArrayList();
boolean found;
while (!pool.isEmpty()) {
found = false;
// Token specifications preceded by any token specification in the pool.
preceded = new HashSet();
for (TokenSpecification ts: pool) {
Set pset = lexis.getPrecedences(ts);
if (pset != null) {
preceded.addAll(pset);
}
}
for (Iterator ite = pool.iterator(); ite.hasNext();) {
TokenSpecification ts = ite.next();
if (!preceded.contains(ts)) {
tokens.add(ts);
ite.remove();
found = true;
}
}
if (!found)
throw new CyclicPrecedenceException("Cyclic token precedence exception: "+cycleMessage(pool));
}
lexis.setTokenSpecifications(tokens);
return lexis;
}
private String cycleMessage(Set tokens)
{
String list = "";
for (TokenSpecification token: tokens)
list += " "+token.getType();
return list;
}
}