org.modelcc.language.metamodel.LanguageModel 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.metamodel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.modelcc.lexer.recognizer.PatternRecognizer;
import org.modelcc.metamodel.Model;
/**
* Language model.
*
* @author Luis Quesada ([email protected]) & Fernando Berzal ([email protected])
*/
public final class LanguageModel extends Model implements Serializable,Cloneable
{
/**
* The start element of this model.
*/
private LanguageElement start;
/**
* Delimiters of this model.
*/
private Set delimiters;
/**
* ModelElement precedence map.
*/
private Map> precedences;
/**
* ModelElement default element map.
*/
private Map> defaultElement;
/**
* Constructor.
* @param elements the set of elements of this model.
* @param start the start element of this model
* @param delimiters the delimiters of this model
* @param precedences the element precedence map
* @param subelements the element subclass map
* @param superelements the element superclass map
* @param classToElement the class to element map
*/
public LanguageModel(Set elements,LanguageElement start,Set delimiters,Map> precedences,Map> subelements,Map superelements,Map classToElement,Map> defaultElement)
{
super(elements,subelements,superelements,classToElement);
// Language model specifics
this.start = start;
this.delimiters = delimiters;
this.precedences = precedences;
this.defaultElement = defaultElement;
}
/**
* @return the start element of this model
*/
public LanguageElement getStart() {
return start;
}
/**
* @return the delimiters of this model
*/
public Set getDelimiters() {
return Collections.unmodifiableSet(delimiters);
}
/**
* @return the element precedences map
*/
public Map> getPrecedences() {
return Collections.unmodifiableMap(precedences);
}
/**
* @return the defaultElement
*/
public Map> getDefaultElement() {
return Collections.unmodifiableMap(defaultElement);
}
@Override
public LanguageModel clone(){
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
ByteArrayOutputStream bOs = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bOs);
oos.writeObject(this);
ois = new ObjectInputStream(new ByteArrayInputStream(bOs.toByteArray()));
LanguageModel ret = (LanguageModel)ois.readObject();
return ret;
} catch (Exception e) {
e.printStackTrace();
return null;
}finally {
if (oos != null)
try {
oos.close();
} catch (IOException e) {
}
if (ois != null)
try {
ois.close();
} catch (IOException e) {
}
}
}
public void addPrecedence(LanguageElement me, LanguageElement other) {
Set precs1 = precedences.get(me);
if (precs1 == null) {
precs1 = new HashSet();
precedences.put(me,precs1);
}
precs1.add(other);
Set precs2 = precedences.get(other);
if (precs2 != null) {
precs2.remove(me);
if (precs2.isEmpty())
precedences.remove(other);
}
}
public boolean checkPrecedences()
{
Set pool = new HashSet();
pool.addAll(getElements());
// Token specifications preceded by any token specification in the pool.
Set precededs;
Iterator ite;
LanguageElement ts;
Set pset;
boolean found; // Whether any new token specification has been added to the sorted list.
while (!pool.isEmpty()) {
found = false;
// Update precededs list.
precededs = new HashSet();
for (ite = pool.iterator();ite.hasNext();) {
ts = ite.next();
pset = precedences.get(ts);
if (pset != null) {
precededs.addAll(pset);
}
}
// Adds news unprecededs.
for (ite = pool.iterator();ite.hasNext();) {
ts = ite.next();
if (!precededs.contains(ts)) {
ite.remove();
found = true;
}
}
if (!found) {
// List of conflicting elements.
// String list = new String();
// for (ite = pool.iterator();ite.hasNext();)
// list += " "+ite.next().getElementClass().getCanonicalName();
return false;
}
}
return true;
}
}