typebuilder.java
来自「plugin for eclipse」· Java 代码 · 共 352 行
JAVA
352 行
/*
* Created on Jun 7, 2005
*
* TODO To change the template for this generated file go to Window -
* Preferences - Java - Code Style - Code Templates
*/
package isis.anp.nesc.ot.types;
import isis.anp.common.CodeLocation;
import isis.anp.common.ObjectTreeBuilderContext;
import isis.anp.common.ParserMessage;
import isis.anp.nesc.ot.AbstractDeclarator;
import isis.anp.nesc.ot.ArrayConstructor;
import isis.anp.nesc.ot.CompoundTypeSpecifier;
import isis.anp.nesc.ot.Declaration;
import isis.anp.nesc.ot.EnumSpecifier;
import isis.anp.nesc.ot.NameConflictException;
import isis.anp.nesc.ot.ParameterTypeList;
import isis.anp.nesc.ot.PointerGroup;
import isis.anp.nesc.ot.StructSpecifier;
import isis.anp.nesc.ot.TypeQualifier;
import isis.anp.nesc.ot.TypeQualifiers;
import isis.anp.nesc.ot.TypeResolutionException;
import isis.anp.nesc.ot.TypeSpecifier;
import isis.anp.nesc.ot.TypedefName;
import isis.anp.nesc.ot.TypeofName;
import isis.anp.nesc.ot.UnionSpecifier;
import isis.anp.nesc.ot.scope.Scope;
import isis.anp.nesc.ot.scope.Symbol;
import java.util.List;
public class TypeBuilder {
protected TypeQualifiers typeQualifiers = new TypeQualifiers();
protected Type typeProduct;
protected AbstractDeclarator nameProduct;
/**
* @return Returns the type.
*/
public Type getType() {
// System.out.println("BuilderObj.getType: "+type);
return typeProduct;
}
/**
* Add a type qualifier to the type being bilt.
*
* @param tq
* Type qualifier
*/
public void addTypeQualifier(TypeQualifier tq) {
typeQualifiers.add(tq);
}
private CompoundType createCompoundType(CompoundTypeSpecifier cts, ObjectTreeBuilderContext ctx) {
if (cts instanceof StructSpecifier) {
return new StructType((StructSpecifier) cts);
} else if (cts instanceof UnionSpecifier) {
return new UnionType((UnionSpecifier) cts);
} else if (cts instanceof EnumSpecifier) {
((EnumSpecifier) cts).addEnumeratorConstantsToScope(ctx);
return new EnumType((EnumSpecifier) cts);
}
// we never get here...
return null;
}
/**
* Add a type specifier to the type being built.
*
* @param ts
* Type specifier.
* @throws TypeResolutionException
*/
public void addTypeSpecifier(TypeSpecifier ts) {
ObjectTreeBuilderContext ctx = ts.getContext();
Scope currentScope = ctx.getCurrentScope();
String specifierName = ts.getSpecifierName();
if (typeProduct == null) {
// no type has been built so far
if (ts instanceof CompoundTypeSpecifier) {
specifierName = ts.getDefNode().getText() + " " + specifierName;
// it's specifier of a compound type
//System.out.println("TypeBuilder:" + specifierName + "it's specifier of a compound type");
CompoundTypeSpecifier cts = (CompoundTypeSpecifier) ts;
CompoundType prevType = (CompoundType) currentScope.findSymbol(specifierName);
if (prevType == null) {
// name not found
//System.out.println("TypeBuilder:" + specifierName + ":name not found");
typeProduct = createCompoundType(cts, ctx);
currentScope.addSymbol((CompoundType)typeProduct);
// continue working on a clone
typeProduct = (Type)typeProduct.clone();
} else {
// name found
//System.out.println("TypeBuilder:" + specifierName + ":name found");
if (prevType.getParentScope().equals(currentScope)) {
// name found in current scope
//System.out.println("TypeBuilder:" + specifierName + ":name found in current scope");
if (prevType.isComplete()) {
// complete type found in current scope
//System.out.println("TypeBuilder:" + specifierName + ":complete type found in current scope");
if (cts.isComplete()) {
// both types would be complete
//System.out.println("TypeBuilder:" + specifierName + ":both types would be complete");
NameConflictException nce = new NameConflictException(
prevType.getNameNode(), cts
.getSpecifierNameNode());
ctx.addMsg(new ParserMessage(ParserMessage.ERROR, nce.getMessage(),
new CodeLocation(cts
.getSpecifierNameNode()), nce));
} else {
// only previous type is complete
//System.out.println("TypeBuilder:" + specifierName + ":only previous type is complete");
typeProduct = createCompoundType(cts, ctx);
((CompoundType) prevType).complete((CompoundType) typeProduct);
}
} else {
// incomplete type found in current scope
//System.out.println("TypeBuilder:" + specifierName + ":incomplete type found in current scope");
if (cts.isComplete()) {
// new type completes previous one
//System.out.println("TypeBuilder:" + specifierName + ":new type completes previous one");
typeProduct = createCompoundType(cts, ctx);
((CompoundType) typeProduct).complete((CompoundType) prevType);
} else {
// both new and previous types are incomplete
//System.out.println("TypeBuilder:" + specifierName + ":both new and previous types are incomplete");
typeProduct = prevType;
// continue working on a clone
typeProduct = (Type)typeProduct.clone();
}
}
} else {
// name found in an upper scope
//System.out.println("TypeBuilder:" + specifierName + ":name found in an upper scope");
if (cts.isComplete()) {
// new type is complete, it shadows the previous one
//System.out.println("TypeBuilder:" + specifierName + ":new type is complete, it shadows the previous one");
typeProduct = createCompoundType(cts, ctx);
currentScope.addSymbol((CompoundType)typeProduct);
// continue working on a clone
typeProduct = (Type)typeProduct.clone();
} else {
// new type is incomplete
//System.out.println("TypeBuilder:" + specifierName + ":new type is incomplete");
if (prevType.isComplete()) {
// previous type is complete
//System.out.println("TypeBuilder:" + specifierName + ":previous type is complete");
typeProduct = createCompoundType(cts, ctx);
prevType.complete((CompoundType)typeProduct);
} else {
// previous type is incomplete
//System.out.println("TypeBuilder:" + specifierName + ":previous type is incomplete");
typeProduct = createCompoundType(cts, ctx);
}
}
}
}
} // end if (ts is a CompoundTypeSpecifier)
else if (ts instanceof TypedefName) {
Symbol symbol = currentScope.findSymbol(specifierName);
if (symbol instanceof TypeReference) {
typeProduct = (TypeReference) symbol;
// continue working on a clone
typeProduct = (Type)typeProduct.clone();
} else {
TypeResolutionException tre = new TypeResolutionException(
"Type not found: " + specifierName, ts
.getSpecifierNameNode());
ctx.addMsg(new ParserMessage(ParserMessage.ERROR, tre.getMessage(),
new CodeLocation(ts.getSpecifierNameNode()), tre));
}
} // end if (ts is a TypedefName)
else if (ts instanceof TypeofName) {
Symbol symbol = currentScope.findSymbol(specifierName);
if (symbol instanceof Declaration) {
typeProduct = ((Declaration) symbol).getType();
// continue working on a clone
typeProduct = (Type)typeProduct.clone();
} else {
TypeResolutionException tre = new TypeResolutionException(
"Declaration not found: " + specifierName, ts
.getSpecifierNameNode());
ctx.addMsg(new ParserMessage(ParserMessage.ERROR, tre.getMessage(),
new CodeLocation(ts.getSpecifierNameNode()), tre));
}
} // end if (ts is a TypeofName)
else {
// ts is a simple type specifier
typeProduct = new SimpleType();
((SimpleType) typeProduct).addTypeSpecifier(ts);
}
// add temporarily stored type qualifier to the type
if(typeProduct!=null) {
typeProduct.addTypeQualifiers(typeQualifiers);
}
} // end if (typeProduct is null)
else if (typeProduct instanceof SimpleType) {
((SimpleType) typeProduct).addTypeSpecifier(ts);
}
else {
TypeResolutionException tre = new TypeResolutionException(
"Error building type: invalid type specifier: "
+ specifierName, ts.getSpecifierNameNode());
ctx.addMsg(new ParserMessage(ParserMessage.ERROR, tre.getMessage(), new CodeLocation(ts
.getSpecifierNameNode()), tre));
}
}
/**
* Add a declarator to a type. The builder extracts the additional type
* information from the declarator (pointer constructors, array constructors
* and function constructors).
*
* @param aDeclr
* The declarator.
* @return @throws
* TypeResolutionException
*/
public AbstractDeclarator addDeclarator(AbstractDeclarator aDeclr)
throws TypeResolutionException {
// resolve pointer group (this will remove everything from the
// pointergroup)
resolvePointerGroup(aDeclr.getPointerGroup());
// resolve array constructors and parameter type lists (this will remove
// all array constructors and parameter type lists from the declarator)
resolveArrayAndFunctionConstructors(aDeclr.getPAList());
// resolve parenthesized declarator
if (aDeclr.getNestedDecl() != null) {
return addDeclarator(aDeclr.getNestedDecl());
}
// set declarator to leaf declarator
this.nameProduct = aDeclr;
// return the leaf declarator
return this.nameProduct;
}
/**
* @param acs
*/
private void resolveArrayAndFunctionConstructors(List cList) {
if (cList.isEmpty())
return;
Object c = cList.remove(cList.size() - 1);
if (c instanceof ArrayConstructor) {
typeProduct = new ArrayType(typeProduct, ((ArrayConstructor) c)
.getSizeExpression());
} else if (c instanceof ParameterTypeList) {
typeProduct = new FunctionType(typeProduct, (ParameterTypeList) c);
}
// continue recursively
resolveArrayAndFunctionConstructors(cList);
}
/**
* @param group
* @throws TypeResolutionException
*/
private void resolvePointerGroup(PointerGroup pg)
throws TypeResolutionException {
if (pg == null)
return;
Object member = pg.removeFirstMember();
if (member == null)
return;
if (member instanceof String) {
// it's a star
if (((String) member).equals("*")) {
// construct a new pointer type enclosing the actual type
typeProduct = new PointerType(typeProduct);
} else {
throw new TypeResolutionException(
"Invalid member in pointer group ('*' expected)",
nameProduct.getDefNode());
}
} else if (member instanceof TypeQualifier) {
// it's const or volatile
if (typeProduct instanceof PointerType) {
typeProduct.addTypeQualifier((TypeQualifier) member);
} else {
throw new TypeResolutionException(
"Cannot apply type qualifier to non-pointer type",
nameProduct.getDefNode());
}
} else {
throw new TypeResolutionException(
"Invalid member in pointer group " + member.toString()
+ " ('*' or const or volatile expected)",
nameProduct.getDefNode());
}
// continue recursively
resolvePointerGroup(pg);
}
public Object clone() {
TypeBuilder rval = new TypeBuilder();
rval.typeQualifiers = (TypeQualifiers) this.typeQualifiers.clone();
// FIXME: do a deep copy
// rval.typeProduct = this.typeProduct.clone();
rval.typeProduct = this.typeProduct;
return rval;
}
/**
* @return Returns the declarator.
*/
public AbstractDeclarator getDeclarator() {
return nameProduct;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?