blob: 723bdfebf3c04b2c81b7bff9a7112926b984dc43 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2005, 2009 IBM Corporation, Zeligsoft Inc., Borland Software Corp., 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 - Initial API and implementation
* E.D.Willink - refactored to separate from OCLAnalyzer and OCLParser
* - Bugs 243976, 259818
* Zeligsoft - Bugs 243976, 255599, 251349
* Borland - Bug 242880
*
* </copyright>
*
* $Id: AbstractOCLParser.java,v 1.6 2009/02/12 00:04:09 cdamus Exp $
*/
package org.eclipse.ocl.parser;
import lpg.lpgjavaruntime.IToken;
import lpg.lpgjavaruntime.NullExportedSymbolsException;
import lpg.lpgjavaruntime.NullTerminalSymbolsException;
import lpg.lpgjavaruntime.ParseErrorCodes;
import lpg.lpgjavaruntime.UndefinedEofSymbolException;
import lpg.lpgjavaruntime.UnimplementedTerminalsException;
import org.eclipse.emf.common.util.EList;
import org.eclipse.ocl.cst.BooleanLiteralExpCS;
import org.eclipse.ocl.cst.CSTFactory;
import org.eclipse.ocl.cst.ClassifierContextDeclCS;
import org.eclipse.ocl.cst.CollectionLiteralExpCS;
import org.eclipse.ocl.cst.CollectionLiteralPartCS;
import org.eclipse.ocl.cst.CollectionRangeCS;
import org.eclipse.ocl.cst.CollectionTypeCS;
import org.eclipse.ocl.cst.CollectionTypeIdentifierEnum;
import org.eclipse.ocl.cst.ContextDeclCS;
import org.eclipse.ocl.cst.DefCS;
import org.eclipse.ocl.cst.DefExpressionCS;
import org.eclipse.ocl.cst.DerValueCS;
import org.eclipse.ocl.cst.EnumLiteralExpCS;
import org.eclipse.ocl.cst.FeatureCallExpCS;
import org.eclipse.ocl.cst.IfExpCS;
import org.eclipse.ocl.cst.InitOrDerValueCS;
import org.eclipse.ocl.cst.InitValueCS;
import org.eclipse.ocl.cst.IntegerLiteralExpCS;
import org.eclipse.ocl.cst.InvCS;
import org.eclipse.ocl.cst.InvOrDefCS;
import org.eclipse.ocl.cst.InvalidLiteralExpCS;
import org.eclipse.ocl.cst.IsMarkedPreCS;
import org.eclipse.ocl.cst.IterateExpCS;
import org.eclipse.ocl.cst.IteratorExpCS;
import org.eclipse.ocl.cst.LetExpCS;
import org.eclipse.ocl.cst.MessageExpCS;
import org.eclipse.ocl.cst.MessageExpKind;
import org.eclipse.ocl.cst.NullLiteralExpCS;
import org.eclipse.ocl.cst.OCLDocumentCS;
import org.eclipse.ocl.cst.OCLExpressionCS;
import org.eclipse.ocl.cst.OCLMessageArgCS;
import org.eclipse.ocl.cst.OperationCS;
import org.eclipse.ocl.cst.OperationCallExpCS;
import org.eclipse.ocl.cst.OperationContextDeclCS;
import org.eclipse.ocl.cst.PackageDeclarationCS;
import org.eclipse.ocl.cst.PathNameCS;
import org.eclipse.ocl.cst.PrePostOrBodyDeclCS;
import org.eclipse.ocl.cst.PrePostOrBodyEnum;
import org.eclipse.ocl.cst.PrimitiveTypeCS;
import org.eclipse.ocl.cst.PropertyContextCS;
import org.eclipse.ocl.cst.RealLiteralExpCS;
import org.eclipse.ocl.cst.SimpleNameCS;
import org.eclipse.ocl.cst.SimpleTypeEnum;
import org.eclipse.ocl.cst.StateExpCS;
import org.eclipse.ocl.cst.StringLiteralExpCS;
import org.eclipse.ocl.cst.TupleLiteralExpCS;
import org.eclipse.ocl.cst.TupleTypeCS;
import org.eclipse.ocl.cst.TypeCS;
import org.eclipse.ocl.cst.UnlimitedNaturalLiteralExpCS;
import org.eclipse.ocl.cst.VariableCS;
import org.eclipse.ocl.cst.VariableExpCS;
import org.eclipse.ocl.internal.l10n.OCLMessages;
import org.eclipse.ocl.lpg.AbstractLexer;
import org.eclipse.ocl.lpg.AbstractParser;
import org.eclipse.ocl.lpg.BasicEnvironment;
import org.eclipse.ocl.lpg.ProblemHandler;
import org.eclipse.ocl.options.ParsingOptions;
import org.eclipse.ocl.options.ProblemOption;
public abstract class AbstractOCLParser
extends AbstractParser {
public AbstractOCLParser(BasicEnvironment environment) {
super(environment);
}
@SuppressWarnings("nls")
public AbstractOCLParser(AbstractLexer lexStream) {
super(lexStream);
try {
super.remapTerminalSymbols(orderedTerminalSymbols(),
OCLParserprs.EOFT_SYMBOL);
} catch (NullExportedSymbolsException e) {
throw new RuntimeException(e.getLocalizedMessage());
} catch (NullTerminalSymbolsException e) {
throw new RuntimeException(e.getLocalizedMessage());
} catch (UnimplementedTerminalsException e) {
java.util.ArrayList<?> unimplemented_symbols = e.getSymbols();
String error = "The Lexer will not scan the following token(s):";
for (int i = 0; i < unimplemented_symbols.size(); i++) {
Integer id = (Integer) unimplemented_symbols.get(i);
error += "\t"
+ OCLParsersym.orderedTerminalSymbols[id.intValue()];
}
throw new RuntimeException(error + "\n");
} catch (UndefinedEofSymbolException e) {
throw new RuntimeException(
"The Lexer does not implement the Eof symbol "
+ OCLParsersym.orderedTerminalSymbols[OCLParserprs.EOFT_SYMBOL]);
}
}
protected PackageDeclarationCS createPackageDeclarationCS(
PathNameCS pathNameCS, EList<ContextDeclCS> contextDecls) {
PackageDeclarationCS result = CSTFactory.eINSTANCE
.createPackageDeclarationCS();
result.setPathNameCS(pathNameCS);
if (contextDecls != null && !contextDecls.isEmpty()) {
result.getContextDecls().addAll(contextDecls);
}
return result;
}
protected PropertyContextCS createPropertyContextCS(PathNameCS pathNameCS,
SimpleNameCS simpleNameCS, TypeCS typeCS,
InitOrDerValueCS initOrDerValueCS) {
PropertyContextCS result = CSTFactory.eINSTANCE
.createPropertyContextCS();
result.setPathNameCS(pathNameCS);
result.setSimpleNameCS(simpleNameCS);
result.setTypeCS(typeCS);
result.setInitOrDerValueCS(initOrDerValueCS);
return result;
}
protected DerValueCS createDerValueCS(InitOrDerValueCS initOrDerValueCS,
OCLExpressionCS oclExpressionCS) {
DerValueCS result = CSTFactory.eINSTANCE.createDerValueCS();
result.setInitOrDerValueCS(initOrDerValueCS);
result.setExpressionCS(oclExpressionCS);
return result;
}
protected InitValueCS createInitValueCS(InitOrDerValueCS initOrDerValueCS,
OCLExpressionCS oclExpressionCS) {
InitValueCS result = CSTFactory.eINSTANCE.createInitValueCS();
result.setInitOrDerValueCS(initOrDerValueCS);
result.setExpressionCS(oclExpressionCS);
return result;
}
/**
* @deprecated As of 1.3, the
* {@link #createClassifierContextDeclCS(PathNameCS, EList)}
* method should be used, instead.
*/
@Deprecated
protected ClassifierContextDeclCS createClassifierContextDeclCS(
PathNameCS pathNameCS, InvOrDefCS invOrDefCS) {
ClassifierContextDeclCS result = CSTFactory.eINSTANCE
.createClassifierContextDeclCS();
result.setPathNameCS(pathNameCS);
result.setInvOrDefCS(invOrDefCS);
// fill in the owned constraints list
for (InvOrDefCS next = invOrDefCS; next != null; next = next
.getInvOrDefCS()) {
result.getConstraints().add(0, next);
}
return result;
}
/**
* Creates a classifier context declaration.
*
* @param pathNameCS
* the concrete syntax of the classifier's qualified name
* @param constraints
* the concrete syntax of the invariant and/or definition
* constraints in the classifier context
* @return the classifier context declaration
*
* @since 1.3
*/
protected ClassifierContextDeclCS createClassifierContextDeclCS(
PathNameCS pathNameCS, EList<InvOrDefCS> constraints) {
ClassifierContextDeclCS result = CSTFactory.eINSTANCE
.createClassifierContextDeclCS();
result.setPathNameCS(pathNameCS);
result.getConstraints().addAll(constraints);
// Create the reversed linked list for 1.2.0 API compatibility
InvOrDefCS tail = null;
for (InvOrDefCS next : constraints) {
next.setInvOrDefCS(tail);
tail = next;
}
result.setInvOrDefCS(tail);
return result;
}
/**
* @deprecated As of 1.3, the
* {@link #createInvCS(SimpleNameCS, OCLExpressionCS)} method
* should be used, instead.
*/
@Deprecated
protected InvCS createInvCS(InvOrDefCS invOrDefCS,
SimpleNameCS simpleNameCS, OCLExpressionCS oclExpressionCS) {
InvCS result = CSTFactory.eINSTANCE.createInvCS();
result.setSimpleNameCS(simpleNameCS);
result.setExpressionCS(oclExpressionCS);
result.setInvOrDefCS(invOrDefCS);
return result;
}
/**
* Creates an invariant constraint.
*
* @param simpleNameCS
* the concrete syntax of the constraint name, or
* <code>null</code> if none
* @param oclExpressionCS
* the concrete syntax of the constraint expression
*
* @return the concrete syntax of the invariant constraint
*
* @since 1.3
*/
protected InvCS createInvCS(SimpleNameCS simpleNameCS,
OCLExpressionCS oclExpressionCS) {
InvCS result = CSTFactory.eINSTANCE.createInvCS();
result.setSimpleNameCS(simpleNameCS);
result.setExpressionCS(oclExpressionCS);
return result;
}
/**
* @deprecated As of 1.3, the
* {@link #createDefCS(SimpleNameCS, OCLExpressionCS)} method
* should be used, instead.
*/
@Deprecated
protected DefCS createDefCS(InvOrDefCS invOrDefCS,
SimpleNameCS simpleNameCS, DefExpressionCS defExpressionCS) {
DefCS result = CSTFactory.eINSTANCE.createDefCS();
result.setSimpleNameCS(simpleNameCS);
result.setDefExpressionCS(defExpressionCS);
result.setInvOrDefCS(invOrDefCS);
return result;
}
/**
* Creates a definition constraint.
*
* @param simpleNameCS
* the concrete syntax of the constraint name
* @param oclExpressionCS
* the concrete syntax of the constraint expression
*
* @return the concrete syntax of the definition constraint
*
* @since 1.3
*/
protected DefCS createDefCS(SimpleNameCS simpleNameCS,
DefExpressionCS defExpressionCS) {
DefCS result = CSTFactory.eINSTANCE.createDefCS();
result.setSimpleNameCS(simpleNameCS);
result.setDefExpressionCS(defExpressionCS);
return result;
}
protected DefExpressionCS createDefExpressionCS(VariableCS variableCS,
OperationCS operationCS, OCLExpressionCS oclExpressionCS) {
DefExpressionCS result = CSTFactory.eINSTANCE.createDefExpressionCS();
result.setVariableCS(variableCS);
result.setOperationCS(operationCS);
result.setExpressionCS(oclExpressionCS);
return result;
}
protected OperationContextDeclCS createOperationContextDeclCS(
OperationCS operationCS,
EList<PrePostOrBodyDeclCS> prePostOrBodyDecls) {
OperationContextDeclCS result = CSTFactory.eINSTANCE
.createOperationContextDeclCS();
result.setOperationCS(operationCS);
result.getPrePostOrBodyDecls().addAll(prePostOrBodyDecls);
return result;
}
protected PrePostOrBodyDeclCS createPrePostOrBodyDeclCS(
PrePostOrBodyEnum kind, SimpleNameCS simpleNameCS,
OCLExpressionCS oclExpressionCS) {
PrePostOrBodyDeclCS result = CSTFactory.eINSTANCE
.createPrePostOrBodyDeclCS();
result.setKind(kind);
result.setSimpleNameCS(simpleNameCS);
result.setExpressionCS(oclExpressionCS);
return result;
}
protected OperationCS createOperationCS(PathNameCS pathNameCS,
SimpleNameCS simpleNameCS, EList<VariableCS> list, TypeCS typeCS) {
OperationCS result = CSTFactory.eINSTANCE.createOperationCS();
result.setPathNameCS(pathNameCS);
result.setSimpleNameCS(simpleNameCS);
result.getParameters().addAll(list);
result.setTypeCS(typeCS);
return result;
}
protected OperationCS createOperationCS(String simpleName,
EList<VariableCS> list, TypeCS typeCS) {
return createOperationCS(null, createSimpleNameCS(
SimpleTypeEnum.IDENTIFIER_LITERAL, simpleName), list, typeCS);
}
protected OperationCallExpCS createOperationCallExpCS(
OCLExpressionCS oclExpressionCS, SimpleNameCS simpleNameCS,
IsMarkedPreCS isMarkedPreCS, EList<OCLExpressionCS> arguments) {
OperationCallExpCS result = CSTFactory.eINSTANCE
.createOperationCallExpCS();
result.setSource(oclExpressionCS);
result.setSimpleNameCS(simpleNameCS);
result.getArguments().addAll(arguments);
if (isAtPre(isMarkedPreCS)) {
result.setIsMarkedPreCS(isMarkedPreCS);
}
return result;
}
/**
* Queries whether the specified <tt>{@literal @pre}</tt> construct was
* actually present in the text. This method is safe with null inputs.
*
* @param atPreCS
* an "at pre" construct or <code>null</code>
* @return <code>true</code> if the <tt>atPreCS</tt> is present;
* <code>false</code>, otherwise
*
* @since 1.3
*/
protected boolean isAtPre(IsMarkedPreCS atPreCS) {
return (atPreCS != null) && atPreCS.isPre();
}
protected OperationCallExpCS createOperationCallExpCS(
OCLExpressionCS oclExpressionCS, SimpleNameCS simpleNameCS,
EList<OCLExpressionCS> arguments) {
return createOperationCallExpCS(oclExpressionCS, simpleNameCS,
createIsMarkedPreCS(false), arguments);
}
protected OperationCallExpCS createOperationCallExpCS(
SimpleNameCS simpleNameCS, IsMarkedPreCS isMarkedPreCS,
EList<OCLExpressionCS> arguments) {
return createOperationCallExpCS(null, simpleNameCS, isMarkedPreCS,
arguments);
}
protected OperationCallExpCS createOperationCallExpCS(
SimpleNameCS simpleNameCS, IsMarkedPreCS isMarkedPreCS,
StateExpCS stateExpCS) {
OperationCallExpCS result = CSTFactory.eINSTANCE
.createOperationCallExpCS();
result.setSimpleNameCS(simpleNameCS);
result.getArguments().add(stateExpCS);
if (isAtPre(isMarkedPreCS)) {
result.setIsMarkedPreCS(isMarkedPreCS);
}
return result;
}
protected StateExpCS createStateExpCS(PathNameCS pathName) {
StateExpCS result = CSTFactory.eINSTANCE.createStateExpCS();
result.getSequenceOfNames().addAll(pathName.getSequenceOfNames());
return result;
}
protected VariableExpCS createVariableExpCS(SimpleNameCS simpleNameCS,
EList<OCLExpressionCS> arguments, IsMarkedPreCS isMarkedPreCS) {
VariableExpCS result = CSTFactory.eINSTANCE.createVariableExpCS();
result.setSimpleNameCS(simpleNameCS);
result.getArguments().addAll(arguments);
if (isAtPre(isMarkedPreCS)) {
result.setIsMarkedPreCS(isMarkedPreCS);
}
return result;
}
protected SimpleNameCS createSimpleNameCS(SimpleTypeEnum type, String value) {
SimpleNameCS result = CSTFactory.eINSTANCE.createSimpleNameCS();
result.setType(type);
result.setValue(unquote(value));
return result;
}
protected PrimitiveTypeCS createPrimitiveTypeCS(SimpleTypeEnum type,
String value) {
PrimitiveTypeCS result = CSTFactory.eINSTANCE.createPrimitiveTypeCS();
result.setType(type);
result.setValue(value);
return result;
}
protected PathNameCS createPathNameCS(String pathName) {
PathNameCS result = CSTFactory.eINSTANCE.createPathNameCS();
result.getSequenceOfNames().add(unquote(pathName));
return result;
}
protected PathNameCS extendPathNameCS(PathNameCS path, String name) {
path.getSequenceOfNames().add(unquote(name));
return path;
}
protected PathNameCS createPathNameCS() {
return CSTFactory.eINSTANCE.createPathNameCS();
}
protected EnumLiteralExpCS createEnumLiteralExpCS(PathNameCS pathNameCS,
SimpleNameCS simpleNameCS) {
EnumLiteralExpCS result = CSTFactory.eINSTANCE.createEnumLiteralExpCS();
result.setPathNameCS(pathNameCS);
result.setSimpleNameCS(simpleNameCS);
return result;
}
/**
* @deprecated Use {@link #createEnumLiteralExpCS(PathNameCS, SimpleNameCS)}
* , instead.
*/
@Deprecated
protected EnumLiteralExpCS createEnumLiteralExpCS(PathNameCS pathNameCS,
String simpleName) {
return createEnumLiteralExpCS(pathNameCS, createSimpleNameCS(
SimpleTypeEnum.IDENTIFIER_LITERAL, simpleName));
}
protected CollectionLiteralExpCS createCollectionLiteralExpCS(
CollectionTypeIdentifierEnum type,
EList<CollectionLiteralPartCS> collectionLiteralParts) {
CollectionLiteralExpCS result = CSTFactory.eINSTANCE
.createCollectionLiteralExpCS();
result.setCollectionType(type);
result.getCollectionLiteralParts().addAll(collectionLiteralParts);
return result;
}
protected CollectionLiteralPartCS createCollectionLiteralPartCS(
OCLExpressionCS oclExpressionCS) {
CollectionLiteralPartCS result = CSTFactory.eINSTANCE
.createCollectionLiteralPartCS();
result.setExpressionCS(oclExpressionCS);
return result;
}
protected CollectionRangeCS createCollectionRangeCS(
OCLExpressionCS oclExpressionCS, OCLExpressionCS lastOCLExpressionCS) {
CollectionRangeCS result = CSTFactory.eINSTANCE
.createCollectionRangeCS();
result.setExpressionCS(oclExpressionCS);
result.setLastExpressionCS(lastOCLExpressionCS);
return result;
}
protected IntegerLiteralExpCS createRangeStart(String integerDotDot,
boolean isNegative) {
String intToken = integerDotDot
.substring(0, integerDotDot.indexOf('.'));
int intValue = Integer.parseInt(intToken);
if (isNegative) {
intValue = -intValue;
}
IntegerLiteralExpCS result = CSTFactory.eINSTANCE
.createIntegerLiteralExpCS();
result.setIntegerSymbol(new Integer(intValue));
result.setSymbol(Integer.toString(intValue));
return result;
}
protected TupleLiteralExpCS createTupleLiteralExpCS(
EList<VariableCS> variables) {
TupleLiteralExpCS result = CSTFactory.eINSTANCE
.createTupleLiteralExpCS();
result.getVariables().addAll(variables);
return result;
}
protected IntegerLiteralExpCS createIntegerLiteralExpCS(String string) {
IntegerLiteralExpCS result = CSTFactory.eINSTANCE
.createIntegerLiteralExpCS();
result.setSymbol(string);
result.setIntegerSymbol(Integer.valueOf(string));
return result;
}
@SuppressWarnings("nls")
protected UnlimitedNaturalLiteralExpCS createUnlimitedNaturalLiteralExpCS(
String string) {
UnlimitedNaturalLiteralExpCS result = CSTFactory.eINSTANCE
.createUnlimitedNaturalLiteralExpCS();
result.setSymbol(string);
if ("*".equals(string)) {
result.setIntegerSymbol(-1);
} else {
result.setIntegerSymbol(Integer.valueOf(string));
}
return result;
}
protected RealLiteralExpCS createRealLiteralExpCS(String string) {
RealLiteralExpCS result = CSTFactory.eINSTANCE.createRealLiteralExpCS();
result.setSymbol(string);
result.setRealSymbol(Double.valueOf(string));
return result;
}
protected StringLiteralExpCS createStringLiteralExpCS(String string) {
StringLiteralExpCS result = CSTFactory.eINSTANCE
.createStringLiteralExpCS();
result.setSymbol(string);
result.setStringSymbol(string);
return result;
}
protected BooleanLiteralExpCS createBooleanLiteralExpCS(String string) {
BooleanLiteralExpCS result = CSTFactory.eINSTANCE
.createBooleanLiteralExpCS();
result.setSymbol(string);
result.setBooleanSymbol(Boolean.valueOf(string));
return result;
}
protected NullLiteralExpCS createNullLiteralExpCS(String string) {
NullLiteralExpCS result = CSTFactory.eINSTANCE.createNullLiteralExpCS();
result.setSymbol(string);
return result;
}
protected InvalidLiteralExpCS createInvalidLiteralExpCS(String string) {
InvalidLiteralExpCS result = CSTFactory.eINSTANCE
.createInvalidLiteralExpCS();
result.setSymbol(string);
return result;
}
protected IteratorExpCS createIteratorExpCS(SimpleNameCS simpleNameCS,
VariableCS variable1, VariableCS variable2,
OCLExpressionCS oclExpressionCS) {
IteratorExpCS result = CSTFactory.eINSTANCE.createIteratorExpCS();
result.setSimpleNameCS(simpleNameCS);
result.setVariable1(variable1);
result.setVariable2(variable2);
result.setBody(oclExpressionCS);
return result;
}
protected IterateExpCS createIterateExpCS(SimpleNameCS simpleNameCS,
VariableCS variable1, VariableCS variable2,
OCLExpressionCS oclExpressionCS) {
IterateExpCS result = CSTFactory.eINSTANCE.createIterateExpCS();
result.setSimpleNameCS(simpleNameCS);
result.setVariable1(variable1);
result.setVariable2(variable2);
result.setBody(oclExpressionCS);
return result;
}
protected VariableCS createVariableCS(String varName, TypeCS typeCS,
OCLExpressionCS oclExpressionCS) {
VariableCS result = CSTFactory.eINSTANCE.createVariableCS();
result.setName(unquote(varName));
result.setTypeCS(typeCS);
result.setInitExpression(oclExpressionCS);
return result;
}
protected CollectionTypeCS createCollectionTypeCS(
CollectionTypeIdentifierEnum collectionType, TypeCS typeCS) {
CollectionTypeCS result = CSTFactory.eINSTANCE.createCollectionTypeCS();
result.setCollectionTypeIdentifier(collectionType);
result.setTypeCS(typeCS);
return result;
}
protected TupleTypeCS createTupleTypeCS(EList<VariableCS> variables) {
TupleTypeCS result = CSTFactory.eINSTANCE.createTupleTypeCS();
result.getVariables().addAll(variables);
return result;
}
protected FeatureCallExpCS createFeatureCallExpCS(
SimpleNameCS simpleNameCS, EList<OCLExpressionCS> arguments,
IsMarkedPreCS isMarkedPreCS) {
FeatureCallExpCS result = CSTFactory.eINSTANCE.createFeatureCallExpCS();
result.setSimpleNameCS(simpleNameCS);
result.getArguments().addAll(arguments);
if (isAtPre(isMarkedPreCS)) {
result.setIsMarkedPreCS(isMarkedPreCS);
}
return result;
}
protected IsMarkedPreCS createIsMarkedPreCS(boolean isMarkedPre) {
IsMarkedPreCS result = CSTFactory.eINSTANCE.createIsMarkedPreCS();
result.setPre(isMarkedPre);
return result;
}
protected LetExpCS createLetExpCS(EList<VariableCS> variables,
OCLExpressionCS oclExpressionCS) {
LetExpCS result = CSTFactory.eINSTANCE.createLetExpCS();
result.getVariables().addAll(variables);
result.setInExpression(oclExpressionCS);
return result;
}
protected IfExpCS createIfExpCS(OCLExpressionCS condition,
OCLExpressionCS thenExpression, OCLExpressionCS elseExpression) {
IfExpCS result = CSTFactory.eINSTANCE.createIfExpCS();
result.setCondition(condition);
result.setThenExpression(thenExpression);
result.setElseExpression(elseExpression);
return result;
}
protected MessageExpCS createMessageExpCS(boolean hasSent,
SimpleNameCS simpleNameCS, EList<OCLMessageArgCS> oclMessageArgs) {
MessageExpCS result = CSTFactory.eINSTANCE.createMessageExpCS();
result.setKind(hasSent
? MessageExpKind.HAS_SENT_LITERAL
: MessageExpKind.SENT_LITERAL);
result.setSimpleNameCS(simpleNameCS);
result.getArguments().addAll(oclMessageArgs);
return result;
}
protected OCLMessageArgCS createOCLMessageArgCS(TypeCS typeCS,
OCLExpressionCS oclExpressionCS) {
OCLMessageArgCS result = CSTFactory.eINSTANCE.createOCLMessageArgCS();
result.setTypeCS(typeCS);
result.setExpression(oclExpressionCS);
return result;
}
/**
* Creates an OCL document CS from a chain of package context declarations.
*
* @param packageDecl
* a chain of package context declarations
* @return the document CS
*
* @since 1.3
*/
protected OCLDocumentCS createOCLDocumentCS(PackageDeclarationCS packageDecl) {
OCLDocumentCS result = CSTFactory.eINSTANCE.createOCLDocumentCS();
for (PackageDeclarationCS decl = packageDecl; decl != null; decl = decl
.getPackageDeclarationCS()) {
result.getPackageDeclarations().add(0, decl);
}
return result;
}
/**
* <p>
* Escaping support based on the QVT specification (8.4.3).
* </p>
* <p>
* All the usual escape characters using backslash can be used including the '\n' new-line character.
* The list of available escape characters are those defined for the Java language.
* <p>
* <p>
* EscapeSequence:
* </p>
* <table border="0" align="left">
* <tr><td><b><tt>\b</tt></b></td> <td><tt>\u0008</tt>: backspace <tt>BS</tt></td></tr>
* <tr><td><b><tt>\t</tt></b></td> <td><tt>\u0009</tt>: horizontal tab <tt>HT</tt></td></tr>
* <tr><td><b><tt>\n</tt></b></td> <td><tt>\u000a</tt>: line feed <tt>LF</tt></td></tr>
* <tr><td><b><tt>\f</tt></b></td> <td><tt>\u000c</tt>: form feed <tt>FF</tt></td></tr>
* <tr><td><b><tt>\r</tt></b></td> <td><tt>\u000d</tt>: carriage return <tt>CR</tt></td></tr>
* <tr><td><b><tt>\"</tt></b></td> <td><tt>\u0022</tt>: double quote <tt>"</tt></td></tr>
* <tr><td><b><tt>\'</tt></b></td> <td><tt>\u0027</tt>: single quote <tt>'</tt></td></tr>
* <tr><td><b><tt>\\</tt></b></td> <td><tt>\u005c</tt>: backslash <tt>\</tt></td></tr>
* <tr><td rowspan="2" valign="top"><b>OctalEscape</b></td> <td><tt>\u0000</tt> to <tt>\u00ff</tt>: from octal value</td></tr>
* <tr><td>\ ZeroToThree OctalDigit OctalDigit</td></tr>
* <tr><td><b>OctalDigit<b></td> <td><tt>0 1 2 3 4 5 6 7</tt></td></tr>
* <tr><td><b>ZeroToThree</b></td> <td><tt>0 1 2 3</tt></td></tr>
* </table>
*
* @param stringLiteral a string literal token with escape notation
* @return the unescaped string
*
* @since 1.3
*/
protected String unescape(IToken stringLiteral) {
String rawString = stringLiteral.toString();
int rawStringLength = rawString.length();
if (rawStringLength <= 2) {
return ""; //$NON-NLS-1$
}
StringBuilder unescapedStringBuilder = null;
boolean isBackslashEscapeProcessingUsed = getEnvironment().isEnabled(
ParsingOptions.USE_BACKSLASH_ESCAPE_PROCESSING);
boolean isNonStdSQEscapingUsed = false;
int n = rawStringLength - 1;
for (int i = 1; i < n; i++) {
char ch = rawString.charAt(i);
if ((isBackslashEscapeProcessingUsed && (ch == '\\'))
|| ((ch == '\'') && isNonStdSQSupported())) {
if (unescapedStringBuilder == null) {
unescapedStringBuilder = new StringBuilder(rawString
.substring(1, i));
}
i++;
if (i >= n) {
reportError(
ParseErrorCodes.INVALID_CODE,
"", stringLiteral.getTokenIndex(), stringLiteral.getTokenIndex(), //$NON-NLS-1$
OCLMessages.StringNotProperlyClosed_ERROR);
}
char nextCh = rawString.charAt(i);
if (ch == '\\') {
switch (nextCh) {
case 'b' :
unescapedStringBuilder.append('\b');
break;
case 't' :
unescapedStringBuilder.append('\t');
break;
case 'n' :
unescapedStringBuilder.append('\n');
break;
case 'f' :
unescapedStringBuilder.append('\f');
break;
case 'r' :
unescapedStringBuilder.append('\r');
break;
case '\"' :
unescapedStringBuilder.append('\"');
break;
case '\'' :
unescapedStringBuilder.append('\'');
break;
case '\\' :
unescapedStringBuilder.append('\\');
break;
default :
// octal escape check
int unescapedChar = -1;
if ((nextCh >= '\u0030') && (nextCh <= '\u0037')) { // octal
// digit
unescapedChar = Character
.getNumericValue(nextCh);
if (i + 1 < n) {
char tmpCh = rawString.charAt(i + 1);
if ((tmpCh >= '\u0030')
&& (tmpCh <= '\u0037')) { // octal digit
unescapedChar = 8 * unescapedChar
+ Character.getNumericValue(tmpCh);
i++;
if (i + 1 < n) {
tmpCh = rawString.charAt(i + 1);
if ((tmpCh >= '\u0030')
&& (tmpCh <= '\u0037') // octal
// digit
&& (nextCh <= '\u0033')) { // most-significant
// digit
// in
// range
// 0..2
unescapedChar = 8
* unescapedChar
+ Character
.getNumericValue(tmpCh);
i++;
}
}
}
}
unescapedStringBuilder
.append((char) unescapedChar);
}
if (unescapedChar < 0) {
reportError(
ParseErrorCodes.INVALID_CODE,
"", stringLiteral.getTokenIndex(), stringLiteral.getTokenIndex(), //$NON-NLS-1$
OCLMessages.InvalidEscapeSequence_ERROR);
}
break;
}
} else { // non-std '' escaping
unescapedStringBuilder.append('\'');
isNonStdSQEscapingUsed = true;
assert nextCh == '\'' : "Unexpected escape sequence in string literal: " + rawString; //$NON-NLS-1$
}
} else if (unescapedStringBuilder != null) {
unescapedStringBuilder.append(ch);
}
}
if (isNonStdSQEscapingUsed) {
// check settings for using non-standard closure iterator
ProblemHandler.Severity sev = getEnvironment().getValue(
ProblemOption.STRING_SINGLE_QUOTE_ESCAPE);
if ((sev != null) && (sev != ProblemHandler.Severity.OK)) {
getEnvironment().problem(
sev,
ProblemHandler.Phase.PARSER,
OCLMessages.bind(OCLMessages.NonStd_SQuote_Escape_,
stringLiteral), "STRING_LITERAL", //$NON-NLS-1$
null);
}
}
return (unescapedStringBuilder == null)
? rawString.substring(1, n)
: unescapedStringBuilder.toString();
}
/**
* To be overridden in parsers which prohibit non-std SQL-like single quote
* escaping (" <tt>''</tt> ").
*
* @return true if such escaping is supported, false otherwise
*
* @since 1.3
*/
protected boolean isNonStdSQSupported() {
return true;
}
}