language Emfatic;

options { k=3;

parserPackageName="org.eclipse.emf.emfatic.core.lang.gen.parser";

astPackageName="org.eclipse.emf.emfatic.core.lang.gen.ast";

astBaseClassName="EmfaticASTNode";

}

sequence compUnit [entry] : packageDecl importStmts topLevelDecls ;

sequence packageDecl : annotations "package" name=qualifiedID SEMI ;

list qualifiedID : id1=ID (qidSeparator idn=ID)* ;

token qidSeparator : DOT | DOLLAR ;

abstract stringLiteralOrQualifiedID : stringLiteralContainer | qualifiedIDContainer ;

sequence stringLiteralContainer : STRING_LITERAL ;

sequence qualifiedIDContainer : qualifiedID ;

list annotations : annotation* ;

sequence annotation : AT source=stringLiteralOrQualifiedID LPAREN keyEqualsValueList RPAREN ;

list keyEqualsValueList : kv1=keyEqualsValue (COMMA kvn=keyEqualsValue)* ;

sequence keyEqualsValue : key=stringLiteralOrQualifiedID EQUALS value=stringLiteralOrQualifiedID ;

list importStmts : importStmt* ;

sequence importStmt : "import" (alias=ID EQUALS)? uri=stringLiteralOrQualifiedID SEMI ;

list topLevelDecls : topLevelDecl* ;

abstract topLevelDecl : (annotations)

subPackageDecl | classDecl | dataTypeDecl | enumDecl | mapEntryDecl ;

sequence subPackageDecl : "package" name=ID LCURLY topLevelDecls RCURLY ;

sequence classDecl : (abstractModifier)?

classKind name=ID

(typeParamsInfo=typeParamsInfo)?

("extends" superTypes=commaListBoundExceptWild)?

(COLON instClassName=boundExceptWildcard)?

LCURLY classMemberDecls RCURLY ;

list commaListBoundExceptWild : tb1=boundExceptWildcard (COMMA tbn=boundExceptWildcard)*;

sequence abstractModifier : "abstract" ;

token classKind : "class" | "interface" ;

sequence typeParamsInfo : LT oneOrMoreTypeParams GT ;

list oneOrMoreTypeParams : tp1=typeParam (COMMA tpn=typeParam)* ;

sequence typeParam : typeVarName=ID (typeBoundsInfo=typeBoundsInfo)? ;

sequence typeBoundsInfo : "extends" oneOrMoreTypeParamBounds ;

list oneOrMoreTypeParamBounds : tb1=boundExceptWildcard (AMP tbn=boundExceptWildcard)*;

sequence boundExceptWildcard : rawTNameOrTVarOrParamzedTName=qualifiedID (LT oneOrMoreTypeArgs GT)? ;

list oneOrMoreTypeArgs : ta1=typeArg (COMMA tan=typeArg)*;

abstract typeArg : boundExceptWildcard | wildcard ;

sequence wildcard : QMARK ( extendsOrSuper boundExceptWildcard )? ;

token extendsOrSuper : "extends" | "super" ;

// there are no array types in EMF

/* dot means package nesting, there are no inner classes in EMF */

list classMemberDecls : classMemberDecl* ;

abstract classMemberDecl : (annotations modifiers) attribute | reference | operation ;

sequence attribute : "attr" typeWithMulti name=ID (EQUALS defaultValueExpr)? SEMI ;

sequence typeWithMulti : name=boundExceptWildcard (multiplicity)? ;

sequence multiplicity : LSQUARE (multiplicityExpr)? RSQUARE ;

sequence multiplicityExpr : lowerBound=simpleMultiplicityExpr (DOT_DOT upperBound=simpleMultiplicityExpr)? ;

token simpleMultiplicityExpr : STAR | PLUS | QMARK | INT_LITERAL ;

sequence reference : referenceKind typeWithMulti (HASH oppositeName=ID)? name=ID SEMI ;

token referenceKind : "ref" | "val" ;

list modifiers : optNegatedModifier* ;

sequence optNegatedModifier : (BANG)? modifier ;

token modifier

// keyword EMF meaning

: "readonly" // EStructuralFeature.changeable = false

| "volatile" // EStructuralFeature.volatile = true

| "transient" // EStructuralFeature.transient = true

| "unsettable" // EStructuralFeature.unsettable = true

| "derived" // EStructuralFeature.derived = true

| "unique" // *ETypedElement.unique = true -- bag?

| "ordered" // *ETypedElement.ordered = true -- random?

| "resolve" // *EReference.resolveProxies = true -- local?

| "id" // EAttribute.id = true

;

abstract defaultValueExpr : boolExpr | intExpr | stringExpr | charExpr ;

sequence boolExpr : trueOrFalse ;

token trueOrFalse : "true" | "false" ;

sequence intExpr : (MINUS)? INT_LITERAL ;

sequence stringExpr : STRING_LITERAL ;

sequence charExpr : CHAR_LITERAL ;

sequence operation : "op" (typeParamsInfo=typeParamsInfo)?

resType=resultType name=ID LPAREN (params)? RPAREN

("throws" exceptions=commaListBoundExceptWild)? SEMI ;

abstract resultType : typeWithMulti | voidContainer ;

sequence voidContainer : "void" ;

list params : p1=param (COMMA pn=param)*;

sequence param : leadingAnnotations=annotations modifiers typeWithMulti name=ID trailingAnnotations=annotations ;

// "transient" means !serializable

sequence dataTypeDecl : (transientModifier)? "datatype" name=ID COLON instClassName=stringLiteralOrQualifiedID SEMI ; // TODO datatypes should accept type parameters

sequence transientModifier : "transient" ;

sequence enumDecl : "enum" name=ID LCURLY enumLiterals RCURLY ;

list enumLiterals : enumLiteral* ;

sequence enumLiteral : leadingAnnotations=annotations name=ID (EQUALS val=INT_LITERAL)? trailingAnnotations=annotations SEMI ;

sequence mapEntryDecl : "mapentry" name=ID COLON key=typeWithMulti MINUS_GT value=typeWithMulti SEMI ;

// the following tokens were added to cater for generics syntax : AMP, LT, GT