#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2514 lines
90 KiB

using System.Drawing;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.AST;
using ASTAttribute = ICSharpCode.NRefactory.Parser.AST.Attribute;
using Types = ICSharpCode.NRefactory.Parser.AST.ClassType;
COMPILER CS /* AW 2002-12-30 renamed from CompilationUnit to CS */
/*----------------------------- token sets -------------------------------*/
string assemblyName = null;
StringBuilder qualidentBuilder = new StringBuilder();
public string ContainingAssembly {
set {
assemblyName = value;
}
}
Token t {
[System.Diagnostics.DebuggerStepThrough]
get {
return lexer.Token;
}
}
Token la {
[System.Diagnostics.DebuggerStepThrough]
get {
return lexer.LookAhead;
}
}
public void Error(string s)
{
if (errDist >= minErrDist) {
errors.Error(la.line, la.col, s);
}
errDist = 0;
}
public override Expression ParseExpression()
{
lexer.NextToken();
Expression expr;
Expr(out expr);
return expr;
}
// Begin ISTypeCast
bool IsTypeCast()
{
if (la.kind != Tokens.OpenParenthesis) {
return false;
}
if (IsSimpleTypeCast()) {
return true;
}
return GuessTypeCast();
}
// "(" ( typeKW [ "[" {","} "]" | "*" ] | void ( "[" {","} "]" | "*" ) ) ")"
// only for built-in types, all others use GuessTypeCast!
bool IsSimpleTypeCast ()
{
// assert: la.kind == _lpar
lexer.StartPeek();
Token pt = lexer.Peek();
if (!IsTypeKWForTypeCast(ref pt)) {
return false;
}
return pt.kind == Tokens.CloseParenthesis;
}
/* !!! Proceeds from current peek position !!! */
bool IsTypeKWForTypeCast(ref Token pt)
{
if (Tokens.TypeKW[pt.kind]) {
pt = lexer.Peek();
if (pt.kind == Tokens.Times || pt.kind == Tokens.OpenSquareBracket) {
return IsPointerOrDims(ref pt);
} else {
return true;
}
} else if (pt.kind == Tokens.Void) {
pt = lexer.Peek();
return IsPointerOrDims(ref pt);
}
return false;
}
/* !!! Proceeds from current peek position !!! */
bool IsTypeNameOrKWForTypeCast(ref Token pt)
{
if (IsTypeKWForTypeCast(ref pt))
return true;
else
return IsTypeNameForTypeCast(ref pt);
}
// TypeName = ident [ "::" ident ] { "." ident } ["<" TypeNameOrKW { "," TypeNameOrKW } ">" ] PointerOrDims
/* !!! Proceeds from current peek position !!! */
bool IsTypeNameForTypeCast(ref Token pt)
{
// ident
if (pt.kind != Tokens.Identifier) {
return false;
}
pt = Peek();
// "::" ident
if (pt.kind == Tokens.DoubleColon) {
pt = Peek();
if (pt.kind != Tokens.Identifier) {
return false;
}
pt = Peek();
}
// { "." ident }
while (pt.kind == Tokens.Dot) {
pt = Peek();
if (pt.kind != Tokens.Identifier) {
return false;
}
pt = Peek();
}
if (pt.kind == Tokens.LessThan) {
do {
pt = Peek();
if (!IsTypeNameOrKWForTypeCast(ref pt)) {
return false;
}
} while (pt.kind == Tokens.Comma);
if (pt.kind != Tokens.GreaterThan) {
return false;
}
pt = Peek();
}
if (pt.kind == Tokens.Times || pt.kind == Tokens.OpenSquareBracket) {
return IsPointerOrDims(ref pt);
}
return true;
}
// "(" TypeName ")" castFollower
bool GuessTypeCast ()
{
// assert: la.kind == _lpar
StartPeek();
Token pt = Peek();
if (!IsTypeNameForTypeCast(ref pt)) {
return false;
}
// ")"
if (pt.kind != Tokens.CloseParenthesis) {
return false;
}
// check successor
pt = Peek();
return Tokens.CastFollower[pt.kind] || (Tokens.TypeKW[pt.kind] && lexer.Peek().kind == Tokens.Dot);
}
// END IsTypeCast
/* Checks whether the next sequences of tokens is a qualident *
* and returns the qualident string */
/* !!! Proceeds from current peek position !!! */
bool IsQualident(ref Token pt, out string qualident)
{
if (pt.kind == Tokens.Identifier) {
qualidentBuilder.Length = 0; qualidentBuilder.Append(pt.val);
pt = Peek();
while (pt.kind == Tokens.Dot || pt.kind == Tokens.DoubleColon) {
pt = Peek();
if (pt.kind != Tokens.Identifier) {
qualident = String.Empty;
return false;
}
qualidentBuilder.Append('.');
qualidentBuilder.Append(pt.val);
pt = Peek();
}
qualident = qualidentBuilder.ToString();
return true;
}
qualident = String.Empty;
return false;
}
/* Skips generic type extensions */
/* !!! Proceeds from current peek position !!! */
/* skip: { "*" | "[" { "," } "]" } */
/* !!! Proceeds from current peek position !!! */
bool IsPointerOrDims (ref Token pt)
{
for (;;) {
if (pt.kind == Tokens.OpenSquareBracket) {
do pt = Peek();
while (pt.kind == Tokens.Comma);
if (pt.kind != Tokens.CloseSquareBracket) return false;
} else if (pt.kind != Tokens.Times) break;
pt = Peek();
}
return true;
}
/* Return the n-th token after the current lookahead token */
void StartPeek()
{
lexer.StartPeek();
}
Token Peek()
{
return lexer.Peek();
}
Token Peek (int n)
{
lexer.StartPeek();
Token x = la;
while (n > 0) {
x = lexer.Peek();
n--;
}
return x;
}
/*-----------------------------------------------------------------*
* Resolver routines to resolve LL(1) conflicts: * *
* These resolution routine return a boolean value that indicates *
* whether the alternative at hand shall be choosen or not. *
* They are used in IF ( ... ) expressions. *
*-----------------------------------------------------------------*/
/* True, if ident is followed by "=" */
bool IdentAndAsgn ()
{
return la.kind == Tokens.Identifier && Peek(1).kind == Tokens.Assign;
}
bool IsAssignment () { return IdentAndAsgn(); }
/* True, if ident is followed by ",", "=", or ";" */
bool IdentAndCommaOrAsgnOrSColon () {
int peek = Peek(1).kind;
return la.kind == Tokens.Identifier &&
(peek == Tokens.Comma || peek == Tokens.Assign || peek == Tokens.Semicolon);
}
bool IsVarDecl () { return IdentAndCommaOrAsgnOrSColon(); }
/* True, if the comma is not a trailing one, *
* like the last one in: a, b, c, */
bool NotFinalComma () {
int peek = Peek(1).kind;
return la.kind == Tokens.Comma &&
peek != Tokens.CloseCurlyBrace && peek != Tokens.CloseSquareBracket;
}
/* True, if "void" is followed by "*" */
bool NotVoidPointer () {
return la.kind == Tokens.Void && Peek(1).kind != Tokens.Times;
}
/* True, if "checked" or "unchecked" are followed by "{" */
bool UnCheckedAndLBrace () {
return la.kind == Tokens.Checked || la.kind == Tokens.Unchecked &&
Peek(1).kind == Tokens.OpenCurlyBrace;
}
/* True, if "." is followed by an ident */
bool DotAndIdent () {
return la.kind == Tokens.Dot && Peek(1).kind == Tokens.Identifier;
}
/* True, if ident is followed by ":" */
bool IdentAndColon () {
return la.kind == Tokens.Identifier && Peek(1).kind == Tokens.Colon;
}
bool IsLabel () { return IdentAndColon(); }
/* True, if ident is followed by "(" */
bool IdentAndLPar () {
return la.kind == Tokens.Identifier && Peek(1).kind == Tokens.OpenParenthesis;
}
/* True, if "catch" is followed by "(" */
bool CatchAndLPar () {
return la.kind == Tokens.Catch && Peek(1).kind == Tokens.OpenParenthesis;
}
bool IsTypedCatch () { return CatchAndLPar(); }
/* True, if "[" is followed by the ident "assembly" */
bool IsGlobalAttrTarget () {
Token pt = Peek(1);
return la.kind == Tokens.OpenSquareBracket &&
pt.kind == Tokens.Identifier && pt.val == "assembly";
}
/* True, if "[" is followed by "," or "]" */
bool LBrackAndCommaOrRBrack () {
int peek = Peek(1).kind;
return la.kind == Tokens.OpenSquareBracket &&
(peek == Tokens.Comma || peek == Tokens.CloseSquareBracket);
}
bool IsDims () { return LBrackAndCommaOrRBrack(); }
/* True, if "[" is followed by "," or "]" */
/* or if the current token is "*" */
bool TimesOrLBrackAndCommaOrRBrack () {
return la.kind == Tokens.Times || LBrackAndCommaOrRBrack();
}
bool IsPointerOrDims () { return TimesOrLBrackAndCommaOrRBrack(); }
bool IsPointer () { return la.kind == Tokens.Times; }
bool SkipGeneric(ref Token pt)
{
if (pt.kind == Tokens.LessThan) {
int braces = 1;
while (braces != 0) {
pt = Peek();
if (pt.kind == Tokens.GreaterThan) {
--braces;
} else if (pt.kind == Tokens.LessThan) {
++braces;
} else if (pt.kind == Tokens.Semicolon || pt.kind == Tokens.OpenCurlyBrace || pt.kind == Tokens.CloseCurlyBrace || pt.kind == Tokens.EOF) {
return false;
}
}
pt = Peek();
}
return true;
}
bool SkipQuestionMark(ref Token pt)
{
if (pt.kind == Tokens.Question) {
pt = Peek();
}
return true;
}
/* True, if lookahead is a primitive type keyword, or */
/* if it is a type declaration followed by an ident */
bool IsLocalVarDecl () {
if (IsYieldStatement()) {
return false;
}
if ((Tokens.TypeKW[la.kind] && Peek(1).kind != Tokens.Dot) || la.kind == Tokens.Void) {
return true;
}
StartPeek();
Token pt = la ;
string ignore;
if (!IsQualident(ref pt, out ignore)) return false;
if (!SkipGeneric(ref pt)) return false;
while (pt.kind == Tokens.Dot) {
pt = Peek();
if (!IsQualident(ref pt, out ignore)) return false;
if (!SkipGeneric(ref pt)) return false;
}
return SkipQuestionMark(ref pt) && IsPointerOrDims(ref pt) && pt.kind == Tokens.Identifier;
}
/* True if lookahead is type parameters (<...>) followed by the specified token */
bool IsGenericFollowedBy(int token)
{
Token t = la;
if (t.kind != Tokens.LessThan) return false;
StartPeek();
return SkipGeneric(ref t) && t.kind == token;
}
bool IsExplicitInterfaceImplementation()
{
StartPeek();
Token pt = la;
pt = Peek();
if (pt.kind == Tokens.Dot || pt.kind == Tokens.DoubleColon)
return true;
if (pt.kind == Tokens.LessThan) {
if (SkipGeneric(ref pt))
return pt.kind == Tokens.Dot;
}
return false;
}
/* True, if lookahead ident is "where" */
bool IdentIsWhere () {
return la.kind == Tokens.Identifier && la.val == "where";
}
/* True, if lookahead ident is "get" */
bool IdentIsGet () {
return la.kind == Tokens.Identifier && la.val == "get";
}
/* True, if lookahead ident is "set" */
bool IdentIsSet () {
return la.kind == Tokens.Identifier && la.val == "set";
}
/* True, if lookahead ident is "add" */
bool IdentIsAdd () {
return la.kind == Tokens.Identifier && la.val == "add";
}
/* True, if lookahead ident is "remove" */
bool IdentIsRemove () {
return la.kind == Tokens.Identifier && la.val == "remove";
}
bool IsNotYieldStatement () {
return !IsYieldStatement();
}
/* True, if lookahead ident is "yield" and than follows a break or return */
bool IsYieldStatement () {
return la.kind == Tokens.Identifier && la.val == "yield" && (Peek(1).kind == Tokens.Return || Peek(1).kind == Tokens.Break);
}
/* True, if lookahead is a local attribute target specifier, *
* i.e. one of "event", "return", "field", "method", *
* "module", "param", "property", or "type" */
bool IsLocalAttrTarget () {
int cur = la.kind;
string val = la.val;
return (cur == Tokens.Event || cur == Tokens.Return ||
(cur == Tokens.Identifier &&
(val == "field" || val == "method" || val == "module" ||
val == "param" || val == "property" || val == "type"))) &&
Peek(1).kind == Tokens.Colon;
}
bool IsShiftRight()
{
Token next = Peek(1);
// TODO : Add col test (seems not to work, lexer bug...) : && la.col == next.col - 1
return (la.kind == Tokens.GreaterThan && next.kind == Tokens.GreaterThan);
}
bool IsTypeReferenceExpression(Expression expr)
{
if (expr is TypeReferenceExpression) return ((TypeReferenceExpression)expr).TypeReference.GenericTypes.Count == 0;
while (expr is FieldReferenceExpression) {
expr = ((FieldReferenceExpression)expr).TargetObject;
if (expr is TypeReferenceExpression) return true;
}
return expr is IdentifierExpression;
}
TypeReferenceExpression GetTypeReferenceExpression(Expression expr, List<TypeReference> genericTypes)
{
TypeReferenceExpression tre = expr as TypeReferenceExpression;
if (tre != null) {
return new TypeReferenceExpression(new TypeReference(tre.TypeReference.Type, tre.TypeReference.PointerNestingLevel, tre.TypeReference.RankSpecifier, genericTypes));
}
StringBuilder b = new StringBuilder();
if (!WriteFullTypeName(b, expr)) {
// there is some TypeReferenceExpression hidden in the expression
while (expr is FieldReferenceExpression) {
expr = ((FieldReferenceExpression)expr).TargetObject;
}
tre = expr as TypeReferenceExpression;
if (tre != null) {
TypeReference typeRef = tre.TypeReference;
if (typeRef.GenericTypes.Count == 0) {
typeRef = typeRef.Clone();
typeRef.Type += "." + b.ToString();
typeRef.GenericTypes.AddRange(genericTypes);
} else {
typeRef = new InnerClassTypeReference(typeRef, b.ToString(), genericTypes);
}
return new TypeReferenceExpression(typeRef);
}
}
return new TypeReferenceExpression(new TypeReference(b.ToString(), 0, null, genericTypes));
}
/* Writes the type name represented through the expression into the string builder. */
/* Returns true when the expression was converted successfully, returns false when */
/* There was an unknown expression (e.g. TypeReferenceExpression) in it */
bool WriteFullTypeName(StringBuilder b, Expression expr)
{
FieldReferenceExpression fre = expr as FieldReferenceExpression;
if (fre != null) {
bool result = WriteFullTypeName(b, fre.TargetObject);
if (b.Length > 0) b.Append('.');
b.Append(fre.FieldName);
return result;
} else if (expr is IdentifierExpression) {
b.Append(((IdentifierExpression)expr).Identifier);
return true;
} else {
return false;
}
}
/*------------------------------------------------------------------------*
*----- LEXER TOKEN LIST ------------------------------------------------*
*------------------------------------------------------------------------*/
/* START AUTOGENERATED TOKENS SECTION */
TOKENS
/* ----- terminal classes ----- */
/* EOF is 0 */
ident
Literal
/* ----- special character ----- */
"="
"+"
"-"
"*"
"/"
"%"
":"
"::"
";"
"?"
"??"
","
"."
"{"
"}"
"["
"]"
"("
")"
">"
"<"
"!"
"&&"
"||"
"~"
"&"
"|"
"^"
"++"
"--"
"=="
"!="
">="
"<="
"<<"
"+="
"-="
"*="
"/="
"%="
"&="
"|="
"^="
"<<="
"->"
/* ----- keywords ----- */
"abstract"
"as"
"base"
"bool"
"break"
"byte"
"case"
"catch"
"char"
"checked"
"class"
"const"
"continue"
"decimal"
"default"
"delegate"
"do"
"double"
"else"
"enum"
"event"
"explicit"
"extern"
"false"
"finally"
"fixed"
"float"
"for"
"foreach"
"goto"
"if"
"implicit"
"in"
"int"
"interface"
"internal"
"is"
"lock"
"long"
"namespace"
"new"
"null"
"object"
"operator"
"out"
"override"
"params"
"private"
"protected"
"public"
"readonly"
"ref"
"return"
"sbyte"
"sealed"
"short"
"sizeof"
"stackalloc"
"static"
"string"
"struct"
"switch"
"this"
"throw"
"true"
"try"
"typeof"
"uint"
"ulong"
"unchecked"
"unsafe"
"ushort"
"using"
"virtual"
"void"
"volatile"
"while"
/* END AUTOGENERATED TOKENS SECTION */
/*------------------------------------------------------------------------*
*----- PARSER -----------------------------------------------------------*
*------------------------------------------------------------------------*/
PRODUCTIONS
/*--- compilation unit: */
CS
(. lexer.NextToken(); /* get the first token */
compilationUnit = new CompilationUnit(); .)
=
{ UsingDirective }
{ IF (IsGlobalAttrTarget()) GlobalAttributeSection }
{ NamespaceMemberDecl }
EOF
.
UsingDirective
(.
string qualident = null; TypeReference aliasedType = null;
.)
=
"using" (. Point startPos = t.Location; .)
Qualident<out qualident>
[ "=" NonArrayType<out aliasedType> ]
";" (.
if (qualident != null && qualident.Length > 0) {
INode node;
if (aliasedType != null) {
node = new UsingDeclaration(qualident, aliasedType);
} else {
node = new UsingDeclaration(qualident);
}
node.StartLocation = startPos;
node.EndLocation = t.EndLocation;
compilationUnit.AddChild(node);
}
.)
.
GlobalAttributeSection
=
"[" (. Point startPos = t.Location; .) ident
(. if (t.val != "assembly") Error("global attribute target specifier (\"assembly\") expected");
string attributeTarget = t.val;
List<ASTAttribute> attributes = new List<ASTAttribute>();
ASTAttribute attribute;
.)
":" Attribute<out attribute> (. attributes.Add(attribute); .)
{ IF (NotFinalComma()) "," Attribute<out attribute> (. attributes.Add(attribute); .)}
[ "," ]
"]" (. AttributeSection section = new AttributeSection(attributeTarget, attributes);
section.StartLocation = startPos;
section.EndLocation = t.EndLocation;
compilationUnit.AddChild(section);
.)
.
Attribute<out ASTAttribute attribute>
(. string qualident;
string alias = null;
.)
=
[ IF (la.kind == Tokens.Identifier && Peek(1).kind == Tokens.DoubleColon)
ident (. alias = t.val; .)
"::"
]
Qualident<out qualident>
(. List<Expression> positional = new List<Expression>();
List<NamedArgumentExpression> named = new List<NamedArgumentExpression>();
string name = (alias != null && alias != "global") ? alias + "." + qualident : qualident;
.)
[ AttributeArguments<positional, named> ] (. attribute = new ICSharpCode.NRefactory.Parser.AST.Attribute(name, positional, named);.)
.
AttributeArguments<List<Expression> positional, List<NamedArgumentExpression> named>
(.
bool nameFound = false;
string name = "";
Expression expr;
.)
=
"("
[
[
IF (IsAssignment()) (. nameFound = true; .)
ident (. name = t.val; .)
"="
] Expr<out expr> (. if (expr != null) {if(name == "") positional.Add(expr);
else { named.Add(new NamedArgumentExpression(name, expr)); name = ""; }
}
.)
{
","
(
IF (IsAssignment()) (. nameFound = true; .)
ident (. name = t.val; .)
"="
| /*Empty*/ (. if (nameFound) Error("no positional argument after named argument"); .)
) Expr<out expr> (. if (expr != null) { if(name == "") positional.Add(expr);
else { named.Add(new NamedArgumentExpression(name, expr)); name = ""; }
}
.)
}
]
")"
.
AttributeSection<out AttributeSection section>
(.
string attributeTarget = "";
List<ASTAttribute> attributes = new List<ASTAttribute>();
ASTAttribute attribute;
.)
=
"[" (. Point startPos = t.Location; .) /*--- attribute target specifier: */
[ IF (IsLocalAttrTarget())
( "event" (. attributeTarget = "event";.)
| "return" (. attributeTarget = "return";.)
| ident (. if (t.val != "field" || t.val != "method" ||
t.val != "module" || t.val != "param" ||
t.val != "property" || t.val != "type")
Error("attribute target specifier (event, return, field," +
"method, module, param, property, or type) expected");
attributeTarget = t.val;
.)
) ":"
]
/*--- attribute list: */
Attribute<out attribute> (. attributes.Add(attribute); .)
{ IF (NotFinalComma()) "," Attribute<out attribute> (. attributes.Add(attribute); .)}
[ "," ]
"]" (. section = new AttributeSection(attributeTarget, attributes);
section.StartLocation = startPos;
section.EndLocation = t.EndLocation;
.)
.
NamespaceMemberDecl
(.
AttributeSection section;
List<AttributeSection> attributes = new List<AttributeSection>();
Modifiers m = new Modifiers();
string qualident;
.)
= /*--- namespace declaration: */
"namespace" (. Point startPos = t.Location; .)
Qualident<out qualident> (. INode node = new NamespaceDeclaration(qualident);
node.StartLocation = startPos;
compilationUnit.AddChild(node);
compilationUnit.BlockStart(node);
.)
"{"
{ UsingDirective }
{ NamespaceMemberDecl }
"}"
[ ";" ] (. node.EndLocation = t.EndLocation;
compilationUnit.BlockEnd();
.)
/*--- type declaration: */
| { AttributeSection<out section> (. attributes.Add(section); .) }
{ TypeModifier<m> }
TypeDecl<m, attributes>
.
TypeDecl<Modifiers m, List<AttributeSection> attributes>
(.
TypeReference type;
List<TypeReference> names;
List<ParameterDeclarationExpression> p = new List<ParameterDeclarationExpression>();
string name;
List<TemplateDefinition> templates;
.)
= /*--- class declaration: */ (. m.Check(Modifier.Classes); .)
"class" (. TypeDeclaration newType = new TypeDeclaration(m.Modifier, attributes);
templates = newType.Templates;
compilationUnit.AddChild(newType);
compilationUnit.BlockStart(newType);
newType.StartLocation = m.GetDeclarationLocation(t.Location);
newType.Type = Types.Class;
.)
ident (. newType.Name = t.val; .)
/* .NET 2.0 */
[ TypeParameterList<templates> ]
[ ClassBase<out names> (. newType.BaseTypes = names; .) ]
/* .NET 2.0 */
{ IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
ClassBody
[ ";" ] (. newType.EndLocation = t.Location;
compilationUnit.BlockEnd();
.)
| /*--- struct declaration: */ (. m.Check(Modifier.StructsInterfacesEnumsDelegates); .)
( "struct" (. TypeDeclaration newType = new TypeDeclaration(m.Modifier, attributes);
templates = newType.Templates;
newType.StartLocation = m.GetDeclarationLocation(t.Location);
compilationUnit.AddChild(newType);
compilationUnit.BlockStart(newType);
newType.Type = Types.Struct;
.)
ident (. newType.Name = t.val; .)
/* .NET 2.0 */
[ TypeParameterList<templates> ]
[ StructInterfaces<out names> (. newType.BaseTypes = names; .) ]
/* .NET 2.0 */
{ IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
StructBody
[ ";" ] (. newType.EndLocation = t.Location;
compilationUnit.BlockEnd();
.)
| /*--- interface declaration: */
"interface" (. TypeDeclaration newType = new TypeDeclaration(m.Modifier, attributes);
templates = newType.Templates;
compilationUnit.AddChild(newType);
compilationUnit.BlockStart(newType);
newType.StartLocation = m.GetDeclarationLocation(t.Location);
newType.Type = Types.Interface;
.)
ident (. newType.Name = t.val; .)
/* .NET 2.0 */
[ TypeParameterList<templates> ]
[ InterfaceBase<out names> (. newType.BaseTypes = names; .) ]
/* .NET 2.0 */
{ IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
InterfaceBody
[ ";" ] (. newType.EndLocation = t.Location;
compilationUnit.BlockEnd();
.)
| /*--- enumeration declaration: */
"enum" (. TypeDeclaration newType = new TypeDeclaration(m.Modifier, attributes);
compilationUnit.AddChild(newType);
compilationUnit.BlockStart(newType);
newType.StartLocation = m.GetDeclarationLocation(t.Location);
newType.Type = Types.Enum;
.)
ident (. newType.Name = t.val; .)
[ ":" IntegralType<out name> (. newType.BaseTypes.Add(new TypeReference(name)); .)
]
EnumBody
[ ";" ] (. newType.EndLocation = t.Location;
compilationUnit.BlockEnd();
.)
| /*--- delegate declaration: */
"delegate" (. DelegateDeclaration delegateDeclr = new DelegateDeclaration(m.Modifier, attributes);
templates = delegateDeclr.Templates;
delegateDeclr.StartLocation = m.GetDeclarationLocation(t.Location);
.)
( IF (NotVoidPointer()) "void" (. delegateDeclr.ReturnType = new TypeReference("void", 0, null); .)
| Type<out type> (. delegateDeclr.ReturnType = type; .)
)
ident (. delegateDeclr.Name = t.val; .)
/* .NET 2.0 */
[ TypeParameterList<templates> ]
"(" [ FormalParameterList<p> (. delegateDeclr.Parameters = p; .)
] ")"
/* .NET 2.0 */
{ IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
";" (. delegateDeclr.EndLocation = t.Location;
compilationUnit.AddChild(delegateDeclr);
.)
)
.
Qualident<out string qualident>
=
ident (. qualidentBuilder.Length = 0; qualidentBuilder.Append(t.val); .)
{ IF (DotAndIdent()) "." ident (. qualidentBuilder.Append('.');
qualidentBuilder.Append(t.val);
.)
} (. qualident = qualidentBuilder.ToString(); .)
.
ClassBase<out List<TypeReference> names>
(.
TypeReference typeRef;
names = new List<TypeReference>();
.)
=
":" ClassType<out typeRef, false> (. if (typeRef != null) { names.Add(typeRef); } .)
{ "," TypeName<out typeRef, false> (. if (typeRef != null) { names.Add(typeRef); } .) }
.
ClassBody
(. AttributeSection section; .)
=
"{"
{ (.List<AttributeSection> attributes = new List<AttributeSection>();
Modifiers m = new Modifiers();
.)
{ AttributeSection<out section> (. attributes.Add(section); .) }
{ MemberModifier<m> }
ClassMemberDecl<m, attributes>
}
"}"
.
StructInterfaces<out List<TypeReference> names>
(.
TypeReference typeRef;
names = new List<TypeReference>();
.)
=
":" TypeName<out typeRef, false> (. if (typeRef != null) { names.Add(typeRef); } .)
{ "," TypeName<out typeRef, false> (. if (typeRef != null) { names.Add(typeRef); } .) }
.
StructBody
(. AttributeSection section; .)
=
"{"
{ (.List<AttributeSection> attributes = new List<AttributeSection>();
Modifiers m = new Modifiers();
.)
{ AttributeSection<out section> (. attributes.Add(section); .) }
{ MemberModifier<m> }
StructMemberDecl<m, attributes>
}
"}"
.
InterfaceBase<out List<TypeReference> names>
(.
TypeReference typeRef;
names = new List<TypeReference>();
.)
=
":" TypeName<out typeRef, false> (. if (typeRef != null) { names.Add(typeRef); } .)
{ "," TypeName<out typeRef, false> (. if (typeRef != null) { names.Add(typeRef); } .) }
.
InterfaceBody
= "{" { InterfaceMemberDecl } "}" .
EnumBody (. FieldDeclaration f; .)
=
"{" [ EnumMemberDecl<out f> (. compilationUnit.AddChild(f); .)
{ IF (NotFinalComma()) "," EnumMemberDecl<out f> (. compilationUnit.AddChild(f); .)
}
[","] ] "}"
.
Type<out TypeReference type>
=
TypeWithRestriction<out type, true, false>
.
TypeWithRestriction<out TypeReference type, bool allowNullable, bool canBeUnbound>
(.
string name;
int pointer = 0;
type = null;
.)
=
( ClassType<out type, canBeUnbound>
| SimpleType<out name> (. type = new TypeReference(name); .)
| "void" "*" (. pointer = 1; type = new TypeReference("void"); .)
) (. List<int> r = new List<int>(); .)
[ IF (allowNullable && la.kind == Tokens.Question) NullableQuestionMark<ref type> ]
{ IF (IsPointerOrDims()) (. int i = 0; .)
( "*" (. ++pointer; .)
| "[" { "," (. ++i; .) } "]" (. r.Add(i); .)
)
}
(. if (type != null) {
type.RankSpecifier = r.ToArray();
type.PointerNestingLevel = pointer;
}
.)
.
NonArrayType<out TypeReference type>
(.
string name;
int pointer = 0;
type = null;
.)
=
( ClassType<out type, false>
| SimpleType<out name> (. type = new TypeReference(name); .)
| "void" "*" (. pointer = 1; type = new TypeReference("void"); .)
)
[ NullableQuestionMark<ref type> ]
{ IF (IsPointer())
"*" (. ++pointer; .)
}
(. if (type != null) { type.PointerNestingLevel = pointer; } .)
.
SimpleType<out string name>
(. name = String.Empty; .)
=
IntegralType<out name>
| "float" (. name = "float"; .)
| "double" (. name = "double"; .)
| "decimal" (. name = "decimal"; .)
| "bool" (. name = "bool"; .)
.
FormalParameterList<List<ParameterDeclarationExpression> parameter>
(.
ParameterDeclarationExpression p;
AttributeSection section;
List<AttributeSection> attributes = new List<AttributeSection>();
.)
=
{ AttributeSection<out section> (.attributes.Add(section); .) }
(
FixedParameter<out p> (. bool paramsFound = false;
p.Attributes = attributes;
parameter.Add(p);
.)
{
"," (. attributes = new List<AttributeSection>(); if (paramsFound) Error("params array must be at end of parameter list"); .)
{ AttributeSection<out section> (.attributes.Add(section); .) }
(
FixedParameter<out p> (. p.Attributes = attributes; parameter.Add(p); .)
| ParameterArray<out p> (. paramsFound = true; p.Attributes = attributes; parameter.Add(p); .)
)
}
| ParameterArray<out p> (. p.Attributes = attributes; parameter.Add(p); .)
)
.
FixedParameter<out ParameterDeclarationExpression p>
(.
TypeReference type;
ParamModifier mod = ParamModifier.In;
System.Drawing.Point start = t.Location;
.)
=
[
"ref" (. mod = ParamModifier.Ref; .)
| "out" (. mod = ParamModifier.Out; .)
]
Type<out type> ident (. p = new ParameterDeclarationExpression(type, t.val, mod); p.StartLocation = start; p.EndLocation = t.Location; .)
.
ParameterArray<out ParameterDeclarationExpression p>
(. TypeReference type; .)
=
"params" Type<out type> ident (. p = new ParameterDeclarationExpression(type, t.val, ParamModifier.Params); .)
.
AccessorModifiers<out Modifiers m>
(. m = new Modifiers(); .)
=
"private" (. m.Add(Modifier.Private, t.Location); .)
| "protected" (. m.Add(Modifier.Protected, t.Location); .)
["internal" (. m.Add(Modifier.Internal, t.Location); .)]
| "internal" (. m.Add(Modifier.Internal, t.Location); .)
["protected" (. m.Add(Modifier.Protected, t.Location); .)]
.
TypeModifier<Modifiers m>
=
"new" (. m.Add(Modifier.New, t.Location); .)
| "public" (. m.Add(Modifier.Public, t.Location); .)
| "protected" (. m.Add(Modifier.Protected, t.Location); .)
| "internal" (. m.Add(Modifier.Internal, t.Location); .)
| "private" (. m.Add(Modifier.Private, t.Location); .)
| "unsafe" (. m.Add(Modifier.Unsafe, t.Location); .)
| "abstract" (. m.Add(Modifier.Abstract, t.Location); .)
| "sealed" (. m.Add(Modifier.Sealed, t.Location); .)
| "static" (. m.Add(Modifier.Static, t.Location); .)
| ident (. if (t.val == "partial") { m.Add(Modifier.Partial, t.Location); } .)
.
ClassType<out TypeReference typeRef, bool canBeUnbound>
(. TypeReference r; typeRef = null; .)
=
TypeName<out r, canBeUnbound> (. typeRef = r; .)
| "object" (. typeRef = new TypeReference("object"); .)
| "string" (. typeRef = new TypeReference("string"); .)
.
IntegralType<out string name> (. name = ""; .)
=
"sbyte" (. name = "sbyte"; .)
| "byte" (. name = "byte"; .)
| "short" (. name = "short"; .)
| "ushort" (. name = "ushort"; .)
| "int" (. name = "int"; .)
| "uint" (. name = "uint"; .)
| "long" (. name = "long"; .)
| "ulong" (. name = "ulong"; .)
| "char" (. name = "char"; .)
.
MemberModifier<Modifiers m>
=
"abstract" (. m.Add(Modifier.Abstract, t.Location); .)
| "extern" (. m.Add(Modifier.Extern, t.Location); .)
| "internal" (. m.Add(Modifier.Internal, t.Location); .)
| "new" (. m.Add(Modifier.New, t.Location); .)
| "override" (. m.Add(Modifier.Override, t.Location); .)
| "private" (. m.Add(Modifier.Private, t.Location); .)
| "protected" (. m.Add(Modifier.Protected, t.Location); .)
| "public" (. m.Add(Modifier.Public, t.Location); .)
| "readonly" (. m.Add(Modifier.ReadOnly, t.Location); .)
| "sealed" (. m.Add(Modifier.Sealed, t.Location); .)
| "static" (. m.Add(Modifier.Static, t.Location); .)
| "unsafe" (. m.Add(Modifier.Unsafe, t.Location); .)
| "virtual" (. m.Add(Modifier.Virtual, t.Location); .)
| "volatile" (. m.Add(Modifier.Volatile, t.Location); .)
.
StructMemberDecl<Modifiers m, List<AttributeSection> attributes>
(.
string qualident = null;
TypeReference type;
Expression expr;
List<ParameterDeclarationExpression> p = new List<ParameterDeclarationExpression>();
Statement stmt = null;
List<VariableDeclaration> variableDeclarators = new List<VariableDeclaration>();
List<TemplateDefinition> templates = new List<TemplateDefinition>();
TypeReference explicitInterface = null;
.)
=
/*--- constant declaration: */ (. m.Check(Modifier.Constants); .)
"const" (.Point startPos = t.Location; .)
Type<out type> ident (. FieldDeclaration fd = new FieldDeclaration(attributes, type, m.Modifier | Modifier.Const);
fd.StartLocation = m.GetDeclarationLocation(startPos);
VariableDeclaration f = new VariableDeclaration(t.val);
fd.Fields.Add(f);
.)
"=" Expr<out expr> (. f.Initializer = expr; .)
{ "," ident (. f = new VariableDeclaration(t.val);
fd.Fields.Add(f);
.)
"=" Expr<out expr> (. f.Initializer = expr; .)
} ";" (. fd.EndLocation = t.EndLocation; compilationUnit.AddChild(fd); .)
/*--- void method (procedure) declaration: */
| IF (NotVoidPointer()) (. m.Check(Modifier.PropertysEventsMethods); .)
"void" (. Point startPos = t.Location; .)
( IF (IsExplicitInterfaceImplementation())
TypeName<out explicitInterface, false>
(.if (la.kind != Tokens.Dot || Peek(1).kind != Tokens.This) {
qualident = TypeReference.StripLastIdentifierFromType(ref explicitInterface);
} .)
| ident (. qualident = t.val; .)
)
/* .NET 2.0 */
[ TypeParameterList<templates> ]
"("
[ FormalParameterList<p> ] ")"
(. MethodDeclaration methodDeclaration = new MethodDeclaration(qualident,
m.Modifier,
new TypeReference("void"),
p,
attributes);
methodDeclaration.StartLocation = m.GetDeclarationLocation(startPos);
methodDeclaration.EndLocation = t.EndLocation;
methodDeclaration.Templates = templates;
if (explicitInterface != null)
methodDeclaration.InterfaceImplementations.Add(new InterfaceImplementation(explicitInterface, qualident));
compilationUnit.AddChild(methodDeclaration);
compilationUnit.BlockStart(methodDeclaration);
.)
/* .NET 2.0 */
{ IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
( Block<out stmt> | ";" ) (. compilationUnit.BlockEnd();
methodDeclaration.Body = (BlockStatement)stmt;
.)
| /*--- event declaration: */ (. m.Check(Modifier.PropertysEventsMethods); .)
"event" (. EventDeclaration eventDecl = new EventDeclaration(null, null, m.Modifier, attributes, null);
eventDecl.StartLocation = t.Location;
compilationUnit.AddChild(eventDecl);
compilationUnit.BlockStart(eventDecl);
EventAddRegion addBlock = null;
EventRemoveRegion removeBlock = null;
.)
Type<out type> (. eventDecl.TypeReference = type; .)
( IF (IsExplicitInterfaceImplementation())
TypeName<out explicitInterface, false>
(. qualident = TypeReference.StripLastIdentifierFromType(ref explicitInterface); .)
(. eventDecl.InterfaceImplementations.Add(new InterfaceImplementation(explicitInterface, qualident)); .)
| ident (. qualident = t.val; .)
)
(. eventDecl.Name = qualident; eventDecl.EndLocation = t.EndLocation; .)
[ "{" (. eventDecl.BodyStart = t.Location; .)
EventAccessorDecls<out addBlock, out removeBlock>
"}" (. eventDecl.BodyEnd = t.EndLocation; .)
]
[ ";" ]
(. compilationUnit.BlockEnd();
eventDecl.AddRegion = addBlock;
eventDecl.RemoveRegion = removeBlock;
.)
/*--- constructor or static contructor declaration: */
| IF (IdentAndLPar()) (. m.Check(Modifier.Constructors | Modifier.StaticConstructors); .)
ident (. string name = t.val; Point startPos = t.Location; .) "(" [ (. m.Check(Modifier.Constructors); .)
FormalParameterList<p>
]
")" (.ConstructorInitializer init = null; .)
[ (. m.Check(Modifier.Constructors); .)
ConstructorInitializer<out init>
] (.
ConstructorDeclaration cd = new ConstructorDeclaration(name, m.Modifier, p, init, attributes);
cd.StartLocation = startPos;
cd.EndLocation = t.EndLocation;
.)
( Block<out stmt> | ";" ) (. cd.Body = (BlockStatement)stmt; compilationUnit.AddChild(cd); .)
/*--- conversion operator declaration: */
| (. m.Check(Modifier.Operators);
if (m.isNone) Error("at least one modifier must be set");
bool isImplicit = true;
Point startPos = Point.Empty;
.)
( "implicit" (. startPos = t.Location; .) | "explicit" (. isImplicit = false; startPos = t.Location; .) )
"operator" Type<out type> (. TypeReference operatorType = type; .)
"(" Type<out type> ident (. string varName = t.val; .) ")"
(. Point endPos = t.Location; .)
( Block<out stmt> | ";" (. stmt = null; .) )
(.
List<ParameterDeclarationExpression> parameters = new List<ParameterDeclarationExpression>();
parameters.Add(new ParameterDeclarationExpression(type, varName));
OperatorDeclaration operatorDeclaration = new OperatorDeclaration(m.Modifier,
attributes,
parameters,
operatorType,
isImplicit ? ConversionType.Implicit : ConversionType.Explicit
);
operatorDeclaration.Body = (BlockStatement)stmt;
operatorDeclaration.StartLocation = m.GetDeclarationLocation(startPos);
operatorDeclaration.EndLocation = endPos;
compilationUnit.AddChild(operatorDeclaration);
.)
/*--- inner type declaration: */
| TypeDecl<m, attributes>
| Type<out type> (. Point startPos = t.Location; .)
(
/*--- operator declaration: */ (. OverloadableOperatorType op;
m.Check(Modifier.Operators);
if (m.isNone) Error("at least one modifier must be set");
.)
"operator" OverloadableOperator<out op> (. TypeReference firstType, secondType = null; string secondName = null; .)
"(" Type<out firstType> ident (. string firstName = t.val; .)
( "," Type<out secondType> ident (. secondName = t.val; .) /* (. if (Tokens.OverloadableUnaryOp[op.kind] && !Tokens.OverloadableBinaryOp[op.kind])
Error("too many operands for unary operator");
.)*/
| /* empty */ /*(. if (Tokens.OverloadableBinaryOp[op.kind]){
Error("too few operands for binary operator");
}
.)*/
)
(. Point endPos = t.Location; .)
")" ( Block<out stmt> | ";" )
(.
List<ParameterDeclarationExpression> parameters = new List<ParameterDeclarationExpression>();
parameters.Add(new ParameterDeclarationExpression(firstType, firstName));
if (secondType != null) {
parameters.Add(new ParameterDeclarationExpression(secondType, secondName));
}
OperatorDeclaration operatorDeclaration = new OperatorDeclaration(m.Modifier,
attributes,
parameters,
type,
op);
operatorDeclaration.Body = (BlockStatement)stmt;
operatorDeclaration.StartLocation = m.GetDeclarationLocation(startPos);
operatorDeclaration.EndLocation = endPos;
compilationUnit.AddChild(operatorDeclaration);
.)
/*--- field declaration: */
| IF (IsVarDecl()) (. m.Check(Modifier.Fields);
FieldDeclaration fd = new FieldDeclaration(attributes, type, m.Modifier);
fd.StartLocation = m.GetDeclarationLocation(startPos);
.)
VariableDeclarator<variableDeclarators>
{ "," VariableDeclarator<variableDeclarators> }
";" (. fd.EndLocation = t.EndLocation; fd.Fields = variableDeclarators; compilationUnit.AddChild(fd); .)
/*--- unqualified indexer declaration (without interface name): */
| (. m.Check(Modifier.Indexers); .)
"this" "[" FormalParameterList<p> "]" (. Point endLocation = t.EndLocation; .) "{" (.
IndexerDeclaration indexer = new IndexerDeclaration(type, p, m.Modifier, attributes);
indexer.StartLocation = startPos;
indexer.EndLocation = endLocation;
indexer.BodyStart = t.Location;
PropertyGetRegion getRegion;
PropertySetRegion setRegion;
.)
AccessorDecls<out getRegion, out setRegion> "}" (.
indexer.BodyEnd = t.EndLocation;
indexer.GetRegion = getRegion;
indexer.SetRegion = setRegion;
compilationUnit.AddChild(indexer);
.)
| IF (la.kind == Tokens.Identifier)
( IF (IsExplicitInterfaceImplementation())
TypeName<out explicitInterface, false>
(.if (la.kind != Tokens.Dot || Peek(1).kind != Tokens.This) {
qualident = TypeReference.StripLastIdentifierFromType(ref explicitInterface);
} .)
| ident (. qualident = t.val; .)
)
(. Point qualIdentEndLocation = t.EndLocation; .)
(
/*--- "not void" method (function) declaration: */
( (. m.Check(Modifier.PropertysEventsMethods); .)
/* .NET 2.0 */
[ TypeParameterList<templates> ]
"(" [ FormalParameterList<p> ] ")" (.
MethodDeclaration methodDeclaration = new MethodDeclaration(qualident,
m.Modifier,
type,
p,
attributes);
if (explicitInterface != null)
methodDeclaration.InterfaceImplementations.Add(new InterfaceImplementation(explicitInterface, qualident));
methodDeclaration.StartLocation = m.GetDeclarationLocation(startPos);
methodDeclaration.EndLocation = t.EndLocation;
methodDeclaration.Templates = templates;
compilationUnit.AddChild(methodDeclaration);
.)
{ IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
( Block<out stmt> | ";" ) (. methodDeclaration.Body = (BlockStatement)stmt; .)
/*--- property declaration: */
| "{" (. PropertyDeclaration pDecl = new PropertyDeclaration(qualident, type, m.Modifier, attributes);
if (explicitInterface != null)
pDecl.InterfaceImplementations.Add(new InterfaceImplementation(explicitInterface, qualident));
pDecl.StartLocation = m.GetDeclarationLocation(startPos);
pDecl.EndLocation = qualIdentEndLocation;
pDecl.BodyStart = t.Location;
PropertyGetRegion getRegion;
PropertySetRegion setRegion;
.)
AccessorDecls<out getRegion, out setRegion>
"}" (.
pDecl.GetRegion = getRegion;
pDecl.SetRegion = setRegion;
pDecl.BodyEnd = t.EndLocation;
compilationUnit.AddChild(pDecl);
.)
)
/*--- qualified indexer declaration (with interface name): */
| (. m.Check(Modifier.Indexers); .)
"." "this" "[" FormalParameterList<p> "]" (.
IndexerDeclaration indexer = new IndexerDeclaration(type, p, m.Modifier, attributes);
indexer.StartLocation = m.GetDeclarationLocation(startPos);
indexer.EndLocation = t.EndLocation;
if (explicitInterface != null)
indexer.InterfaceImplementations.Add(new InterfaceImplementation(explicitInterface, "this"));
PropertyGetRegion getRegion;
PropertySetRegion setRegion;
.)
"{" (. Point bodyStart = t.Location; .)
AccessorDecls<out getRegion, out setRegion>
"}" (. indexer.BodyStart = bodyStart;
indexer.BodyEnd = t.EndLocation;
indexer.GetRegion = getRegion;
indexer.SetRegion = setRegion;
compilationUnit.AddChild(indexer);
.)
)
)
.
ClassMemberDecl<Modifiers m, List<AttributeSection> attributes>
(. Statement stmt = null; .)
=
StructMemberDecl<m, attributes>
| /*--- destructor declaration: */ (. m.Check(Modifier.Destructors); Point startPos = t.Location; .)
"~" ident (. DestructorDeclaration d = new DestructorDeclaration(t.val, m.Modifier, attributes);
d.Modifier = m.Modifier;
d.StartLocation = m.GetDeclarationLocation(startPos);
.)
"(" ")" (. d.EndLocation = t.EndLocation; .) ( Block<out stmt> | ";" ) (.
d.Body = (BlockStatement)stmt;
compilationUnit.AddChild(d);
.)
.
InterfaceMemberDecl
(.
TypeReference type;
AttributeSection section;
Modifier mod = Modifier.None;
List<AttributeSection> attributes = new List<AttributeSection>();
List<ParameterDeclarationExpression> parameters = new List<ParameterDeclarationExpression>();
string name;
PropertyGetRegion getBlock;
PropertySetRegion setBlock;
Point startLocation = new Point(-1, -1);
List<TemplateDefinition> templates = new List<TemplateDefinition>();
.)
=
{ AttributeSection<out section> (. attributes.Add(section); .)}
[ "new" (. mod = Modifier.New; startLocation = t.Location; .) ]
(
/*--- interface void method (procedure) declaration: */
IF (NotVoidPointer()) "void" (. if (startLocation.X == -1) startLocation = t.Location; .) ident (. name = t.val; .)
[ TypeParameterList<templates> ]
"(" [ FormalParameterList<parameters> ] ")"
{ IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
";"
(. MethodDeclaration md = new MethodDeclaration(name, mod, new TypeReference("void"), parameters, attributes);
md.StartLocation = startLocation;
md.EndLocation = t.EndLocation;
md.Templates = templates;
compilationUnit.AddChild(md);
.)
| (
Type<out type> (. if (startLocation.X == -1) startLocation = t.Location; .)
(
ident (. name = t.val; Point qualIdentEndLocation = t.EndLocation; .)
(
/*--- interface "not void" method (function) declaration: */
/* .NET 2.0 */
[ TypeParameterList<templates> ]
"(" [ FormalParameterList<parameters> ] ")"
/* .NET 2.0 */
{ IF (IdentIsWhere()) TypeParameterConstraintsClause<templates> }
";" (. MethodDeclaration md = new MethodDeclaration(name, mod, type, parameters, attributes);
md.StartLocation = startLocation;
md.EndLocation = t.EndLocation;
md.Templates = templates;
compilationUnit.AddChild(md);
.)
/*--- interface property declaration: */
| (. PropertyDeclaration pd = new PropertyDeclaration(name, type, mod, attributes); compilationUnit.AddChild(pd); .)
"{" (. Point bodyStart = t.Location;.) InterfaceAccessors<out getBlock, out setBlock> "}" (. pd.GetRegion = getBlock; pd.SetRegion = setBlock; pd.StartLocation = startLocation; pd.EndLocation = qualIdentEndLocation; pd.BodyStart = bodyStart; pd.BodyEnd = t.EndLocation; .)
)
/*--- interface indexer declaration: */
| "this" "[" FormalParameterList<parameters> "]" (.Point bracketEndLocation = t.EndLocation; .) (. IndexerDeclaration id = new IndexerDeclaration(type, parameters, mod, attributes); compilationUnit.AddChild(id); .)
"{" (. Point bodyStart = t.Location;.) InterfaceAccessors<out getBlock, out setBlock> "}" (. id.GetRegion = getBlock; id.SetRegion = setBlock; id.StartLocation = startLocation; id.EndLocation = bracketEndLocation; id.BodyStart = bodyStart; id.BodyEnd = t.EndLocation;.)
)
/*--- interface event declaration: */
| "event" (. if (startLocation.X == -1) startLocation = t.Location; .) Type<out type> ident (. EventDeclaration ed = new EventDeclaration(type, t.val, mod, attributes, null);
compilationUnit.AddChild(ed);
.)
";" (. ed.StartLocation = startLocation; ed.EndLocation = t.EndLocation; .)
)
)
.
EnumMemberDecl<out FieldDeclaration f>
(.
Expression expr = null;
List<AttributeSection> attributes = new List<AttributeSection>();
AttributeSection section = null;
VariableDeclaration varDecl = null;
.)
=
{ AttributeSection<out section> (. attributes.Add(section); .) }
ident (. f = new FieldDeclaration(attributes);
varDecl = new VariableDeclaration(t.val);
f.Fields.Add(varDecl);
f.StartLocation = t.Location;
.)
[ "=" Expr<out expr> (. varDecl.Initializer = expr; .) ]
.
AccessorDecls<out PropertyGetRegion getBlock, out PropertySetRegion setBlock>
(.
List<AttributeSection> attributes = new List<AttributeSection>();
AttributeSection section;
getBlock = null;
setBlock = null;
Modifiers modifiers = null;
.)
=
{ AttributeSection<out section> (. attributes.Add(section); .) }
[ AccessorModifiers<out modifiers> ]
(
IF (IdentIsGet())
GetAccessorDecl<out getBlock, attributes>
(. if (modifiers != null) {getBlock.Modifier = modifiers.Modifier; } .)
[ (. attributes = new List<AttributeSection>(); modifiers = null; .)
{ AttributeSection<out section> (. attributes.Add(section); .) }
[ AccessorModifiers<out modifiers> ]
SetAccessorDecl<out setBlock, attributes>
(. if (modifiers != null) {setBlock.Modifier = modifiers.Modifier; } .)
]
| IF (IdentIsSet())
SetAccessorDecl<out setBlock, attributes>
(. if (modifiers != null) {setBlock.Modifier = modifiers.Modifier; } .)
[ (. attributes = new List<AttributeSection>(); modifiers = null; .)
{ AttributeSection<out section> (. attributes.Add(section); .) }
[ AccessorModifiers<out modifiers> ]
GetAccessorDecl<out getBlock, attributes>
(. if (modifiers != null) {getBlock.Modifier = modifiers.Modifier; } .)
]
| ident (. Error("get or set accessor declaration expected"); .)
)
.
GetAccessorDecl<out PropertyGetRegion getBlock, List<AttributeSection> attributes>
(. Statement stmt = null; .)
=
ident /* "get" is not a keyword! */
(. if (t.val != "get") Error("get expected"); .)
(. Point startLocation = t.Location; .)
( Block<out stmt> | ";" )
(. getBlock = new PropertyGetRegion((BlockStatement)stmt, attributes); .)
(. getBlock.StartLocation = startLocation; getBlock.EndLocation = t.EndLocation; .)
.
SetAccessorDecl<out PropertySetRegion setBlock, List<AttributeSection> attributes>
(. Statement stmt = null; .)
=
ident /* "set" is not a keyword! */
(. if (t.val != "set") Error("set expected"); .)
(. Point startLocation = t.Location; .)
( Block<out stmt> | ";" )
(. setBlock = new PropertySetRegion((BlockStatement)stmt, attributes); .)
(. setBlock.StartLocation = startLocation; setBlock.EndLocation = t.EndLocation; .)
.
EventAccessorDecls<out EventAddRegion addBlock, out EventRemoveRegion removeBlock>
(. AttributeSection section;
List<AttributeSection> attributes = new List<AttributeSection>();
Statement stmt;
addBlock = null;
removeBlock = null;
.)
=
{ AttributeSection<out section> (. attributes.Add(section); .) }
(
IF (IdentIsAdd()) (. addBlock = new EventAddRegion(attributes); .)
AddAccessorDecl<out stmt> (. attributes = new List<AttributeSection>(); addBlock.Block = (BlockStatement)stmt; .)
{ AttributeSection<out section> (. attributes.Add(section); .)}
RemoveAccessorDecl<out stmt> (. removeBlock = new EventRemoveRegion(attributes); removeBlock.Block = (BlockStatement)stmt; .)
| IF (IdentIsRemove())
RemoveAccessorDecl <out stmt> (. removeBlock = new EventRemoveRegion(attributes); removeBlock.Block = (BlockStatement)stmt; attributes = new List<AttributeSection>(); .)
{ AttributeSection<out section> (. attributes.Add(section); .) }
AddAccessorDecl<out stmt> (. addBlock = new EventAddRegion(attributes); addBlock.Block = (BlockStatement)stmt; .)
| ident (. Error("add or remove accessor declaration expected"); .)
)
.
InterfaceAccessors<out PropertyGetRegion getBlock, out PropertySetRegion setBlock>
(.
AttributeSection section;
List<AttributeSection> attributes = new List<AttributeSection>();
getBlock = null; setBlock = null;
PropertyGetSetRegion lastBlock = null;
.)
=
{ AttributeSection<out section> (. attributes.Add(section); .) }
(. Point startLocation = la.Location; .)
(
IF (IdentIsGet()) ident (. getBlock = new PropertyGetRegion(null, attributes); .)
| IF (IdentIsSet()) ident (. setBlock = new PropertySetRegion(null, attributes); .)
| ident (. Error("set or get expected"); .)
)
";"
(. if (getBlock != null) { getBlock.StartLocation = startLocation; getBlock.EndLocation = t.EndLocation; }
if (setBlock != null) { setBlock.StartLocation = startLocation; setBlock.EndLocation = t.EndLocation; }
attributes = new List<AttributeSection>(); .)
[
{ AttributeSection<out section> (. attributes.Add(section); .) }
(. startLocation = la.Location; .)
(
IF (IdentIsGet()) ident (. if (getBlock != null) Error("get already declared");
else { getBlock = new PropertyGetRegion(null, attributes); lastBlock = getBlock; }
.)
| IF (IdentIsSet()) ident (. if (setBlock != null) Error("set already declared");
else { setBlock = new PropertySetRegion(null, attributes); lastBlock = setBlock; }
.)
| ident (. Error("set or get expected"); .)
)
";"
(. if (lastBlock != null) { lastBlock.StartLocation = startLocation; lastBlock.EndLocation = t.EndLocation; } .)
]
.
VariableDeclarator<List<VariableDeclaration> fieldDeclaration>
(. Expression expr = null; .)
=
ident (. VariableDeclaration f = new VariableDeclaration(t.val); .)
[ "=" VariableInitializer<out expr> (. f.Initializer = expr; .) ] (. fieldDeclaration.Add(f); .)
.
Block<out Statement stmt> /* not BlockStatement because of EmbeddedStatement */
=
"{" (. BlockStatement blockStmt = new BlockStatement();
blockStmt.StartLocation = t.EndLocation;
compilationUnit.BlockStart(blockStmt);
if (!parseMethodContents) lexer.SkipCurrentBlock();
.)
{ Statement }
"}" (.
stmt = blockStmt;
blockStmt.EndLocation = t.EndLocation;
compilationUnit.BlockEnd();
.)
.
AddAccessorDecl<out Statement stmt>
(.stmt = null;.)
=
/* "add" is not a keyword!? */
ident (. if (t.val != "add") Error("add expected"); .)
Block<out stmt>
.
RemoveAccessorDecl<out Statement stmt>
(.stmt = null;.)
=
/* "remove" is not a keyword!? */
ident (. if (t.val != "remove") Error("remove expected"); .)
Block<out stmt>
.
ConstructorInitializer<out ConstructorInitializer ci>
(. Expression expr; ci = new ConstructorInitializer(); .)
=
":"
(
"base" (. ci.ConstructorInitializerType = ConstructorInitializerType.Base; .)
| "this" (. ci.ConstructorInitializerType = ConstructorInitializerType.This; .)
)
"("
[ Argument<out expr> (. if (expr != null) { ci.Arguments.Add(expr); } .) { "," Argument<out expr> (. if (expr != null) { ci.Arguments.Add(expr); } .) } ]
")"
.
VariableInitializer<out Expression initializerExpression>
(. TypeReference type = null; Expression expr = null; initializerExpression = null; .)
=
Expr<out initializerExpression>
| ArrayInitializer<out initializerExpression>
| "stackalloc" Type<out type> "[" Expr<out expr> "]" (. initializerExpression = new StackAllocExpression(type, expr); .)
| /* workaround for coco bug? doesn't work in Expr production in this case. */
"default" "(" Type<out type> ")" (. initializerExpression = new DefaultValueExpression(type); .)
.
OverloadableOperator<out OverloadableOperatorType op>
(. op = OverloadableOperatorType.None; .)
=
"+" (. op = OverloadableOperatorType.Add; .)
| "-" (. op = OverloadableOperatorType.Subtract; .)
| "!" (. op = OverloadableOperatorType.Not; .)
| "~" (. op = OverloadableOperatorType.BitNot; .)
| "++" (. op = OverloadableOperatorType.Increment; .)
| "--" (. op = OverloadableOperatorType.Decrement; .)
| "true" (. op = OverloadableOperatorType.True; .)
| "false" (. op = OverloadableOperatorType.False; .)
| "*" (. op = OverloadableOperatorType.Multiply; .)
| "/" (. op = OverloadableOperatorType.Divide; .)
| "%" (. op = OverloadableOperatorType.Modulus; .)
| "&" (. op = OverloadableOperatorType.BitwiseAnd; .)
| "|" (. op = OverloadableOperatorType.BitwiseOr; .)
| "^" (. op = OverloadableOperatorType.ExclusiveOr; .)
| "<<" (. op = OverloadableOperatorType.ShiftLeft; .)
| "==" (. op = OverloadableOperatorType.Equality; .)
| "!=" (. op = OverloadableOperatorType.InEquality; .)
| "<" (. op = OverloadableOperatorType.LessThan; .)
| ">=" (. op = OverloadableOperatorType.GreaterThanOrEqual; .)
| "<=" (. op = OverloadableOperatorType.LessThanOrEqual; .)
| ">" (. op = OverloadableOperatorType.GreaterThan; .) [ ">" (. op = OverloadableOperatorType.ShiftRight; .) ]
.
Argument<out Expression argumentexpr>
(.
Expression expr;
FieldDirection fd = FieldDirection.None;
.)
=
[
"ref" (. fd = FieldDirection.Ref; .)
| "out" (. fd = FieldDirection.Out; .)
]
Expr<out expr> (. argumentexpr = fd != FieldDirection.None ? argumentexpr = new DirectionExpression(fd, expr) : expr; .)
.
AssignmentOperator<out AssignmentOperatorType op>
(. op = AssignmentOperatorType.None; .)
=
"=" (. op = AssignmentOperatorType.Assign; .)
| "+=" (. op = AssignmentOperatorType.Add; .)
| "-=" (. op = AssignmentOperatorType.Subtract; .)
| "*=" (. op = AssignmentOperatorType.Multiply; .)
| "/=" (. op = AssignmentOperatorType.Divide; .)
| "%=" (. op = AssignmentOperatorType.Modulus; .)
| "&=" (. op = AssignmentOperatorType.BitwiseAnd; .)
| "|=" (. op = AssignmentOperatorType.BitwiseOr; .)
| "^=" (. op = AssignmentOperatorType.ExclusiveOr; .)
| "<<=" (. op = AssignmentOperatorType.ShiftLeft; .)
| IF (la.kind == Tokens.GreaterThan && Peek(1).kind == Tokens.GreaterEqual)
">" ">=" (. op = AssignmentOperatorType.ShiftRight; .)
.
ArrayInitializer<out Expression outExpr>
(.
Expression expr = null;
ArrayInitializerExpression initializer = new ArrayInitializerExpression();
.)
=
"{"
[ VariableInitializer<out expr>
(. if (expr != null) { initializer.CreateExpressions.Add(expr); } .)
{ IF (NotFinalComma())
"," VariableInitializer<out expr>
(. if (expr != null) { initializer.CreateExpressions.Add(expr); } .)
}
[ "," ]
]
"}" (. outExpr = initializer; .)
.
LocalVariableDecl<out Statement stmt>
(.
TypeReference type;
VariableDeclaration var = null;
LocalVariableDeclaration localVariableDeclaration;
.)
=
Type<out type> (. localVariableDeclaration = new LocalVariableDeclaration(type); localVariableDeclaration.StartLocation = t.Location; .)
LocalVariableDeclarator<out var> (. localVariableDeclaration.Variables.Add(var); .)
{ "," LocalVariableDeclarator<out var> (. localVariableDeclaration.Variables.Add(var); .) }
(. stmt = localVariableDeclaration; .)
.
LocalVariableDeclarator<out VariableDeclaration var>
(. Expression expr = null; .)
=
/* ident (. var = new VariableDeclaration(t.val); .) [ "=" LocalVariableInitializer<out expr> (. var.Initializer = expr; .) ]*/
ident (. var = new VariableDeclaration(t.val); .) [ "=" VariableInitializer<out expr> (. var.Initializer = expr; .) ]
.
/*
LocalVariableInitializer<out Expression expr>
(. expr = null; .)
=
Expr<out expr>
| ArrayInitializer<out expr>
.
*/
Statement
(.
TypeReference type;
Expression expr;
Statement stmt = null;
Point startPos = la.Location;
.)
=
(
/*--- labeled statement: */
IF (IsLabel()) ident (. compilationUnit.AddChild(new LabelStatement(t.val)); .)
":" Statement
/*--- local constant declaration: */
| "const" Type<out type> (. LocalVariableDeclaration var = new LocalVariableDeclaration(type, Modifier.Const); string ident = null; var.StartLocation = t.Location; .)
ident (. ident = t.val; .)
"=" Expr<out expr> (. var.Variables.Add(new VariableDeclaration(ident, expr)); .)
{ "," ident (. ident = t.val; .) "=" Expr<out expr> (. var.Variables.Add(new VariableDeclaration(ident, expr)); .) }
";" (. compilationUnit.AddChild(var); .)
/*--- local variable declaration: */
| IF (IsLocalVarDecl()) LocalVariableDecl<out stmt> ";" (. compilationUnit.AddChild(stmt); .)
| EmbeddedStatement<out stmt> (. compilationUnit.AddChild(stmt); .)
/* LL(1) confict: LocalVariableDecl *
* <-> StatementExpr *
* ident {"." ident} { "[" Expr ... */
)
(.
if (stmt != null) {
stmt.StartLocation = startPos;
stmt.EndLocation = t.EndLocation;
}
.)
.
EmbeddedStatement<out Statement statement>
(.
TypeReference type = null;
Expression expr = null;
Statement embeddedStatement = null;
statement = null;
.)
=
Block<out statement>
/*--- empty statement: */
| ";" (. statement = new EmptyStatement(); .)
/*--- checked / unchecked statement: */
| IF (UnCheckedAndLBrace()) (. Statement block; bool isChecked = true; .)
("checked" | "unchecked" (. isChecked = false;.) )
Block<out block> (. statement = isChecked ? (Statement)new CheckedStatement(block) : (Statement)new UncheckedStatement(block); .)
/*--- selection statements (if, switch): */
| "if" (. Statement elseStatement = null; .)
"(" Expr<out expr> ")"
EmbeddedStatement<out embeddedStatement>
[ "else" EmbeddedStatement<out elseStatement> ]
(. statement = elseStatement != null ? new IfElseStatement(expr, embeddedStatement, elseStatement) : new IfElseStatement(expr, embeddedStatement); .)
(. if (elseStatement is IfElseStatement && (elseStatement as IfElseStatement).TrueStatement.Count == 1) {
/* else if-section (otherwise we would have a BlockStatment) */
(statement as IfElseStatement).ElseIfSections.Add(
new ElseIfSection((elseStatement as IfElseStatement).Condition,
(elseStatement as IfElseStatement).TrueStatement[0]));
(statement as IfElseStatement).ElseIfSections.AddRange((elseStatement as IfElseStatement).ElseIfSections);
(statement as IfElseStatement).FalseStatement = (elseStatement as IfElseStatement).FalseStatement;
} .)
| "switch" (. List<SwitchSection> switchSections = new List<SwitchSection>(); SwitchSection switchSection; .)
"(" Expr<out expr> ")"
"{" { SwitchSection<out switchSection> (. switchSections.Add(switchSection); .) }
"}" (. statement = new SwitchStatement(expr, switchSections); .)
/*--- iteration statements (while, do, for, foreach): */
| "while" "(" Expr<out expr> ")"
EmbeddedStatement<out embeddedStatement> (. statement = new DoLoopStatement(expr, embeddedStatement, ConditionType.While, ConditionPosition.Start);.)
| "do" EmbeddedStatement<out embeddedStatement> "while"
"(" Expr<out expr> ")" ";" (. statement = new DoLoopStatement(expr, embeddedStatement, ConditionType.While, ConditionPosition.End); .)
| "for" (. List<Statement> initializer = null; List<Statement> iterator = null; .)
"(" [ ForInitializer<out initializer> ] ";"
[ Expr<out expr> ] ";"
[ ForIterator<out iterator> ] ")"
EmbeddedStatement<out embeddedStatement> (. statement = new ForStatement(initializer, expr, iterator, embeddedStatement); .)
| "foreach" "(" Type<out type> ident (. string varName = t.val; Point start = t.Location;.)
"in" Expr<out expr> ")"
EmbeddedStatement<out embeddedStatement> (. statement = new ForeachStatement(type, varName , expr, embeddedStatement);
statement.EndLocation = t.EndLocation;
.)
/*--- jump statements (break, contine, goto, return, throw): */
| "break" ";" (. statement = new BreakStatement(); .)
| "continue" ";" (. statement = new ContinueStatement(); .)
| GotoStatement<out statement>
| IF (IsYieldStatement()) ident ( "return" Expr<out expr> (. statement = new YieldStatement(new ReturnStatement(expr)); .)
| "break" (. statement = new YieldStatement(new BreakStatement()); .) ) ";"
| "return" [ Expr<out expr> ] ";" (. statement = new ReturnStatement(expr); .)
| "throw" [ Expr<out expr> ] ";" (. statement = new ThrowStatement(expr); .)
/*--- expression statement: */
| StatementExpr<out statement> ";"
/*--- try statement: */
| TryStatement<out statement>
/*--- lock satement: */
| "lock" "(" Expr<out expr> ")"
EmbeddedStatement<out embeddedStatement> (. statement = new LockStatement(expr, embeddedStatement); .)
/*--- using statement: */
| (.Statement resourceAcquisitionStmt = null; .)
"using" "("
ResourceAcquisition<out resourceAcquisitionStmt> ")"
EmbeddedStatement<out embeddedStatement> (. statement = new UsingStatement(resourceAcquisitionStmt, embeddedStatement); .)
/*--- unsafe statement: */
| "unsafe" Block<out embeddedStatement> (. statement = new UnsafeStatement(embeddedStatement); .)
/*--- fixed statement: */
| "fixed"
"(" Type<out type> (. if (type.PointerNestingLevel == 0) Error("can only fix pointer types");
List<VariableDeclaration> pointerDeclarators = new List<VariableDeclaration>(1);
.)
ident (. string identifier = t.val; .)
"=" Expr<out expr> (. pointerDeclarators.Add(new VariableDeclaration(identifier, expr)); .)
{
"," ident (. identifier = t.val; .)
"=" Expr<out expr> (. pointerDeclarators.Add(new VariableDeclaration(identifier, expr)); .)
}
")" EmbeddedStatement<out embeddedStatement> (. statement = new FixedStatement(type, pointerDeclarators, embeddedStatement); .)
.
ForInitializer<out List<Statement> initializer>
(.
Statement stmt;
initializer = new List<Statement>();
.)
=
IF (IsLocalVarDecl()) LocalVariableDecl<out stmt> (. initializer.Add(stmt);.)
| StatementExpr<out stmt> (.initializer.Add(stmt);.) { "," StatementExpr<out stmt> (. initializer.Add(stmt);.) }
.
ForIterator<out List<Statement> iterator>
(.
Statement stmt;
iterator = new List<Statement>();
.)
=
StatementExpr<out stmt> (. iterator.Add(stmt);.) { "," StatementExpr<out stmt> (. iterator.Add(stmt); .) }
.
SwitchSection<out SwitchSection stmt>
(.
SwitchSection switchSection = new SwitchSection();
CaseLabel label;
.)
=
SwitchLabel<out label> (. switchSection.SwitchLabels.Add(label); .)
{
SwitchLabel<out label> (. switchSection.SwitchLabels.Add(label); .)
}
(. compilationUnit.BlockStart(switchSection); .)
Statement { Statement }
(.
compilationUnit.BlockEnd();
stmt = switchSection;
.)
.
SwitchLabel<out CaseLabel label>
(. Expression expr = null; label = null; .)
=
"case" Expr<out expr> ":" (. label = new CaseLabel(expr); .)
| "default" ":" (. label = new CaseLabel(); .)
.
TryStatement<out Statement tryStatement>
(.
Statement blockStmt = null, finallyStmt = null;
List<CatchClause> catchClauses = null;
.)
=
"try" Block<out blockStmt>
(
CatchClauses<out catchClauses> [ "finally" Block<out finallyStmt> ]
| "finally" Block<out finallyStmt>
)
(.
tryStatement = new TryCatchStatement(blockStmt, catchClauses, finallyStmt);
.)
.
CatchClauses<out List<CatchClause> catchClauses>
(.
catchClauses = new List<CatchClause>();
.)
=
"catch" (. string identifier;
Statement stmt;
TypeReference typeRef;
.)
/*--- general catch clause (as only catch clause) */
(
Block<out stmt> (. catchClauses.Add(new CatchClause(stmt)); .)
/*--- specific catch clause */
| "(" ClassType<out typeRef, false> (. identifier = null; .)
[ ident (. identifier = t.val; .) ]
")" Block<out stmt>
(. catchClauses.Add(new CatchClause(typeRef, identifier, stmt)); .)
{ IF (IsTypedCatch()) "catch" "(" ClassType<out typeRef, false> (. identifier = null; .)
[ ident (. identifier = t.val; .) ]
")" Block<out stmt>
(. catchClauses.Add(new CatchClause(typeRef, identifier, stmt)); .) }
/*--- general catch clause (after specific catch clauses, optional) */
[ "catch" Block<out stmt> (. catchClauses.Add(new CatchClause(stmt)); .) ]
)
.
GotoStatement<out Statement stmt>
(. Expression expr; stmt = null; .)
=
"goto"
(
ident (. stmt = new GotoStatement(t.val); .) ";"
| "case" Expr<out expr> ";" (. stmt = new GotoCaseStatement(expr); .)
| "default" ";" (. stmt = new GotoCaseStatement(null); .)
)
.
ResourceAcquisition<out Statement stmt>
(.
stmt = null;
Expression expr;
.)
=
(
IF (IsLocalVarDecl()) LocalVariableDecl<out stmt>
| Expr<out expr> /* LL(1) conflict resoltion: *
* check if next is Qualident followed by ident *
* ==> LocalVariableDecl *
* new problem: first set of ResourceAcquisition changes */
(. stmt = new StatementExpression(expr); .)
)
.
StatementExpr<out Statement stmt>
(. Expression expr; .)
=
Expr<out expr>
/* The grammar allows only assignments or method invocations here, */
/* but we don't enforce that here */
(. stmt = new StatementExpression(expr); .)
.
Expr<out Expression expr>
(. expr = null; Expression expr1 = null, expr2 = null; AssignmentOperatorType op; .)
=
UnaryExpr<out expr>
/*--- conditional expression: */
(
( AssignmentOperator<out op> Expr<out expr1> (. expr = new AssignmentExpression(expr, op, expr1); .) )
| IF (la.kind == Tokens.GreaterThan && Peek(1).kind == Tokens.GreaterEqual)
( AssignmentOperator<out op> Expr<out expr1> (. expr = new AssignmentExpression(expr, op, expr1); .) )
| (
ConditionalOrExpr<ref expr>
[ "??" Expr<out expr1> (. expr = new BinaryOperatorExpression(expr, BinaryOperatorType.NullCoalescing, expr1); .) ]
[ "?" Expr<out expr1> ":" Expr<out expr2> (. expr = new ConditionalExpression(expr, expr1, expr2); .) ]
)
)
.
UnaryExpr<out Expression uExpr>
(.
TypeReference type = null;
Expression expr;
ArrayList expressions = new ArrayList();
uExpr = null;
.)
=
{
/* IF (Tokens.UnaryOp[la.kind] || IsTypeCast()) */
(
"+" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Plus)); .)
| "-" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Minus)); .)
| "!" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Not)); .)
| "~" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.BitNot)); .)
| "*" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Star)); .)
| "++" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Increment)); .)
| "--" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.Decrement)); .)
| "&" (. expressions.Add(new UnaryOperatorExpression(UnaryOperatorType.BitWiseAnd)); .)
/*--- cast expression: */
/* Problem: "(" Type ")" from here and *
* "(" Expr ")" from PrimaryExpr *
* Solution: (in IsTypeCast()) */
| IF (IsTypeCast()) "(" Type<out type> ")" (. expressions.Add(new CastExpression(type)); .)
)
}
PrimaryExpr<out expr> (. for (int i = 0; i < expressions.Count; ++i) {
Expression nextExpression = i + 1 < expressions.Count ? (Expression)expressions[i + 1] : expr;
if (expressions[i] is CastExpression) {
((CastExpression)expressions[i]).Expression = nextExpression;
} else {
((UnaryOperatorExpression)expressions[i]).Expression = nextExpression;
}
}
if (expressions.Count > 0) {
uExpr = (Expression)expressions[0];
} else {
uExpr = expr;
}
.)
.
PrimaryExpr<out Expression pexpr>
(.
TypeReference type = null;
List<TypeReference> typeList = null;
bool isArrayCreation = false;
Expression expr;
pexpr = null;
.)
=
(
"true" (.pexpr = new PrimitiveExpression(true, "true"); .)
| "false" (.pexpr = new PrimitiveExpression(false, "false"); .)
| "null" (.pexpr = new PrimitiveExpression(null, "null"); .) /* from literal token */
| Literal (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| IF (la.kind == Tokens.Identifier && Peek(1).kind == Tokens.DoubleColon)
ident (. type = new TypeReference(t.val); .)
"::" (. pexpr = new TypeReferenceExpression(type); .)
ident (. if (type.Type == "global") { type.IsGlobal = true; type.Type = t.val; } else type.Type += "." + t.val; .)
/*--- simple name: */
| ident (. pexpr = new IdentifierExpression(t.val); .)
/*--- parenthesized expression: */
| "(" Expr<out expr> ")" (. pexpr = new ParenthesizedExpression(expr); .)
| /*--- predefined type member access: */
(. string val = null; .)
(
"bool" (. val = "bool"; .)
| "byte" (. val = "byte"; .)
| "char" (. val = "char"; .)
| "decimal" (. val = "decimal"; .)
| "double" (. val = "double"; .)
| "float" (. val = "float"; .)
| "int" (. val = "int"; .)
| "long" (. val = "long"; .)
| "object" (. val = "object"; .)
| "sbyte" (. val = "sbyte"; .)
| "short" (. val = "short"; .)
| "string" (. val = "string"; .)
| "uint" (. val = "uint"; .)
| "ulong" (. val = "ulong"; .)
| "ushort" (. val = "ushort"; .)
) (. t.val = ""; .) "." ident (. pexpr = new FieldReferenceExpression(new TypeReferenceExpression(val), t.val); .)
/*--- this access: */
| "this" (. pexpr = new ThisReferenceExpression(); .)
/*--- base access: */
| "base" (. Expression retExpr = new BaseReferenceExpression(); .)
(
"." ident (. retExpr = new FieldReferenceExpression(retExpr, t.val); .)
| "[" Expr<out expr> (. List<Expression> indices = new List<Expression>(); if (expr != null) { indices.Add(expr); } .)
{ "," Expr<out expr> (. if (expr != null) { indices.Add(expr); } .) }
"]" (. retExpr = new IndexerExpression(retExpr, indices); .)
) (. pexpr = retExpr; .)
| "new" NonArrayType<out type>
(. List<Expression> parameters = new List<Expression>(); .)
/*--- delegate / object creation expression: */
/* Note: a delegate creation expression allow only a single Expr */
/* not an argument list, but this is not distinguished here */
(
"(" (. ObjectCreateExpression oce = new ObjectCreateExpression(type, parameters); .)
[ Argument<out expr> (. if (expr != null) { parameters.Add(expr); } .)
{ "," Argument<out expr> (. if (expr != null) { parameters.Add(expr); } .) }
]
")" (. pexpr = oce; .)
| "[" /*--- array creation expression: */
(. isArrayCreation = true; ArrayCreateExpression ace = new ArrayCreateExpression(type); pexpr = ace; .)
(. int dims = 0; List<int> ranks = new List<int>(); .)
(
{ "," (. dims += 1; .) }
"]" (. ranks.Add(dims); dims = 0; .)
{ "[" { "," (. ++dims; .) } "]" (. ranks.Add(dims); dims = 0; .) }
(. ace.CreateType.RankSpecifier = ranks.ToArray(); .)
ArrayInitializer<out expr> (. ace.ArrayInitializer = (ArrayInitializerExpression)expr; .)
| Expr<out expr> (. if (expr != null) parameters.Add(expr); .)
{ "," (. dims += 1; .)
Expr<out expr> (. if (expr != null) parameters.Add(expr); .)
}
"]" (. ranks.Add(dims); ace.Arguments = parameters; dims = 0; .)
{ "[" { "," (. ++dims; .) } "]" (. ranks.Add(dims); dims = 0; .) }
(. ace.CreateType.RankSpecifier = ranks.ToArray(); .)
[ ArrayInitializer<out expr> (. ace.ArrayInitializer = (ArrayInitializerExpression)expr; .) ]
)
)
| "typeof" "("
(
IF (NotVoidPointer()) "void" (. type = new TypeReference("void"); .)
| TypeWithRestriction<out type, true, true>
) ")" (. pexpr = new TypeOfExpression(type); .)
| IF (la.kind == Tokens.Default && Peek(1).kind == Tokens.OpenParenthesis)
/* possible conflict with switch's default */
"default" "(" Type<out type> ")" (. pexpr = new DefaultValueExpression(type); .)
| "sizeof" "(" Type<out type> ")" (. pexpr = new SizeOfExpression(type); .)
| "checked" "(" Expr<out expr> ")" (. pexpr = new CheckedExpression(expr); .)
| "unchecked" "(" Expr<out expr> ")" (. pexpr = new UncheckedExpression(expr); .)
| "delegate" AnonymousMethodExpr<out expr> (. pexpr = expr; .)
)
{
(
"++" (. pexpr = new UnaryOperatorExpression(pexpr, UnaryOperatorType.PostIncrement); .)
| "--" (. pexpr = new UnaryOperatorExpression(pexpr, UnaryOperatorType.PostDecrement); .)
)
/*--- member access */
| "->" ident (. pexpr = new PointerReferenceExpression(pexpr, t.val); .)
| "." ident (. pexpr = new FieldReferenceExpression(pexpr, t.val);.)
/* member access on generic type */
| ( IF (IsGenericFollowedBy(Tokens.Dot) && IsTypeReferenceExpression(pexpr))
TypeArgumentList<out typeList, false> )
"." ident
(. pexpr = new FieldReferenceExpression(GetTypeReferenceExpression(pexpr, typeList), t.val);.)
/*--- invocation expression: */
| "(" (. List<Expression> parameters = new List<Expression>(); .)
[ Argument<out expr> (. if (expr != null) {parameters.Add(expr);} .)
{ "," Argument<out expr> (. if (expr != null) {parameters.Add(expr);} .)
} ] ")" (. pexpr = new InvocationExpression(pexpr, parameters); .)
| ( IF (IsGenericFollowedBy(Tokens.OpenParenthesis)) TypeArgumentList<out typeList, false> )
"(" (. List<Expression> parameters = new List<Expression>(); .)
[ Argument<out expr> (. if (expr != null) {parameters.Add(expr);} .)
{ "," Argument<out expr> (. if (expr != null) {parameters.Add(expr);} .)
} ] ")" (. pexpr = new InvocationExpression(pexpr, parameters, typeList); .)
/*--- element access */
| (. if (isArrayCreation) Error("element access not allow on array creation");
List<Expression> indices = new List<Expression>();
.)
"[" Expr<out expr> (. if (expr != null) { indices.Add(expr); } .)
{ "," Expr<out expr> (. if (expr != null) { indices.Add(expr); } .)
} "]" (. pexpr = new IndexerExpression(pexpr, indices); .)
}
.
AnonymousMethodExpr<out Expression outExpr>
(.
AnonymousMethodExpression expr = new AnonymousMethodExpression();
expr.StartLocation = t.Location;
Statement stmt;
List<ParameterDeclarationExpression> p = new List<ParameterDeclarationExpression>();
outExpr = expr;
.)
=
[
"("
[ FormalParameterList<p> (. expr.Parameters = p; .) ]
")"
]
/*--- ParseExpression doesn't set a compilation unit, */
/*--- so we can't use block then -> skip body of anonymous method */
(. if (compilationUnit != null) { .)
Block<out stmt> (. expr.Body = (BlockStatement)stmt; .)
(. } else { .)
"{"
(. lexer.SkipCurrentBlock(); .)
"}"
(. } .)
(. expr.EndLocation = t.Location; .)
.
ConditionalOrExpr<ref Expression outExpr>
(. Expression expr; .)
=
ConditionalAndExpr<ref outExpr> { "||" UnaryExpr<out expr> ConditionalAndExpr<ref expr> (. outExpr = new BinaryOperatorExpression(outExpr, BinaryOperatorType.LogicalOr, expr); .) }
.
ConditionalAndExpr<ref Expression outExpr>
(. Expression expr; .)
=
InclusiveOrExpr<ref outExpr> { "&&" UnaryExpr<out expr> InclusiveOrExpr<ref expr> (. outExpr = new BinaryOperatorExpression(outExpr, BinaryOperatorType.LogicalAnd, expr); .) }
.
InclusiveOrExpr<ref Expression outExpr>
(. Expression expr; .)
=
ExclusiveOrExpr<ref outExpr> { "|" UnaryExpr<out expr> ExclusiveOrExpr<ref expr> (. outExpr = new BinaryOperatorExpression(outExpr, BinaryOperatorType.BitwiseOr, expr); .) }
.
ExclusiveOrExpr<ref Expression outExpr>
(. Expression expr; .)
=
AndExpr<ref outExpr> { "^" UnaryExpr<out expr> AndExpr<ref expr> (. outExpr = new BinaryOperatorExpression(outExpr, BinaryOperatorType.ExclusiveOr, expr); .) }
.
AndExpr<ref Expression outExpr>
(. Expression expr; .)
=
EqualityExpr<ref outExpr> { "&" UnaryExpr<out expr> EqualityExpr<ref expr> (. outExpr = new BinaryOperatorExpression(outExpr, BinaryOperatorType.BitwiseAnd, expr); .) }
.
EqualityExpr<ref Expression outExpr>
(.
Expression expr;
BinaryOperatorType op = BinaryOperatorType.None;
.)
=
RelationalExpr<ref outExpr>
{
(
"!=" (. op = BinaryOperatorType.InEquality; .)
| "==" (. op = BinaryOperatorType.Equality; .)
)
UnaryExpr<out expr> RelationalExpr<ref expr> (. outExpr = new BinaryOperatorExpression(outExpr, op, expr); .)
}
.
RelationalExpr<ref Expression outExpr>
(.
TypeReference type;
Expression expr;
BinaryOperatorType op = BinaryOperatorType.None;
.)
=
ShiftExpr<ref outExpr>
{
( "<" (. op = BinaryOperatorType.LessThan; .)
| ">" (. op = BinaryOperatorType.GreaterThan; .)
| "<=" (. op = BinaryOperatorType.LessThanOrEqual; .)
| ">=" (. op = BinaryOperatorType.GreaterThanOrEqual; .)
)
UnaryExpr<out expr>
ShiftExpr<ref expr>
(. outExpr = new BinaryOperatorExpression(outExpr, op, expr); .)
|
( "is"
TypeWithRestriction<out type, false, false>
(. outExpr = new TypeOfIsExpression(outExpr, type); .)
| "as"
TypeWithRestriction<out type, false, false>
(. outExpr = new CastExpression(type, outExpr, CastType.TryCast); .)
)
}
.
ShiftExpr<ref Expression outExpr>
(.
Expression expr;
BinaryOperatorType op = BinaryOperatorType.None;
.)
=
AdditiveExpr<ref outExpr>
{
( "<<" (. op = BinaryOperatorType.ShiftLeft; .)
| IF (IsShiftRight()) (
">" ">" (. op = BinaryOperatorType.ShiftRight; .)
)
)
UnaryExpr<out expr> AdditiveExpr<ref expr> (. outExpr = new BinaryOperatorExpression(outExpr, op, expr); .)
}
.
AdditiveExpr<ref Expression outExpr>
(.
Expression expr;
BinaryOperatorType op = BinaryOperatorType.None;
.)
=
MultiplicativeExpr<ref outExpr>
{
(
"+" (. op = BinaryOperatorType.Add; .)
| "-" (. op = BinaryOperatorType.Subtract; .)
)
UnaryExpr<out expr> MultiplicativeExpr<ref expr> (. outExpr = new BinaryOperatorExpression(outExpr, op, expr); .)
}
.
MultiplicativeExpr<ref Expression outExpr>
(.
Expression expr;
BinaryOperatorType op = BinaryOperatorType.None;
.)
=
{
(
"*" (. op = BinaryOperatorType.Multiply; .)
| "/" (. op = BinaryOperatorType.Divide; .)
| "%" (. op = BinaryOperatorType.Modulus; .)
)
UnaryExpr<out expr> (. outExpr = new BinaryOperatorExpression(outExpr, op, expr); .)
}
.
/* .NET 2.0 rules */
TypeName<out TypeReference typeRef, bool canBeUnbound>
(. List<TypeReference> typeArguments = null;
string alias = null;
string qualident;
.)
=
[ IF (la.kind == Tokens.Identifier && Peek(1).kind == Tokens.DoubleColon)
ident (. alias = t.val; .)
"::"
]
Qualident<out qualident>
[TypeArgumentList<out typeArguments, canBeUnbound>]
(.
if (alias == null) {
typeRef = new TypeReference(qualident, typeArguments);
} else if (alias == "global") {
typeRef = new TypeReference(qualident, typeArguments);
typeRef.IsGlobal = true;
} else {
typeRef = new TypeReference(alias + "." + qualident, typeArguments);
}
.)
{ IF (DotAndIdent())
"." (. typeArguments = null; .)
Qualident<out qualident>
[TypeArgumentList<out typeArguments, canBeUnbound>]
(. typeRef = new InnerClassTypeReference(typeRef, qualident, typeArguments); .)
}
.
NullableQuestionMark<ref TypeReference typeRef>
(. List<TypeReference> typeArguments = new List<TypeReference>(1); .)
=
"?"
(.
if (typeRef != null) typeArguments.Add(typeRef);
typeRef = new TypeReference("System.Nullable", typeArguments);
.)
.
TypeArgumentList<out List<TypeReference> types, bool canBeUnbound>
(.
types = new List<TypeReference>();
TypeReference type = null;
.)
=
"<"
( IF (canBeUnbound && (la.kind == Tokens.GreaterThan || la.kind == Tokens.Comma))
(. types.Add(TypeReference.Null); .)
{ "," (. types.Add(TypeReference.Null); .) }
| Type<out type> (. types.Add(type); .)
{ "," Type<out type> (. types.Add(type); .) }
)
">"
.
TypeParameterList<List<TemplateDefinition> templates>
(.
AttributeSection section;
List<AttributeSection> attributes = new List<AttributeSection>();
.)
=
"<" { AttributeSection<out section> (. attributes.Add(section); .) }
ident (. templates.Add(new TemplateDefinition(t.val, attributes)); .)
{ "," { AttributeSection<out section> (. attributes.Add(section); .) }
ident (. templates.Add(new TemplateDefinition(t.val, attributes)); .)}
">"
.
TypeParameterConstraintsClause<List<TemplateDefinition> templates>
(. string name = ""; TypeReference type; .)
=
ident (. if (t.val != "where") Error("where expected"); .)
ident (. name = t.val; .)
":"
TypeParameterConstraintsClauseBase<out type> (.
TemplateDefinition td = null;
foreach (TemplateDefinition d in templates) {
if (d.Name == name) {
td = d;
break;
}
}
if ( td != null) { td.Bases.Add(type); }
.)
{ "," TypeParameterConstraintsClauseBase<out type> (.
td = null;
foreach (TemplateDefinition d in templates) {
if (d.Name == name) {
td = d;
break;
}
}
if ( td != null) { td.Bases.Add(type); }
.) }
.
TypeParameterConstraintsClauseBase<out TypeReference type>
(. TypeReference t; type = null; .)
=
"struct" (. type = new TypeReference("struct"); .)
| "class" (. type = new TypeReference("struct"); .)
| "new" "(" ")" (. type = new TypeReference("struct"); .)
| Type<out t> (. type = t; .)
.
END CS.