ECMA-334 C# Grammar (recovered)
A.1 Lexical grammar
.1 Line terminators
.2 White space
.3 Comments
.4 Tokens
.5 Unicode character escape sequences
.6 Identifiers
.7 Keywords
.8 Literals
.9 Operators and punctuators
.10 Pre-processing directives
A.2 Syntactic grammar
.1 Basic concepts
.2 Types
.3 Variables
.4 Expressions
.5 Statements
.6 Classes
.7 Structs
.8 Arrays
.9 Interfaces
.10 Enums
.11 Delegates
.12 Attributes
input:
input-section-part*
input-section-part:
input-element* new-line
pp-directive
input-element:
whitespace
comment
token
new-line:
Carriage return character (U+000D)
Line feed character (U+000A)
Carriage return character (U+000D) followed by line feed character (U+000A)
Next line character (U+0085)
Line separator character (U+2028)
Paragraph separator character (U+2029)
whitespace:
whitespace-character+
whitespace-character:
Any character with Unicode class Zs
Horizontal tab character (U+0009)
Vertical tab character (U+000B)
Form feed character (U+000C)
comment:
single-line-comment
delimited-comment
single-line-comment:
"//" input-character*
input-character:
Any Unicode character except a new-line-character
new-line-character:
Carriage return character (U+000D)
Line feed character (U+000A)
Next line character (U+0085)
Line separator character (U+2028)
Paragraph separator character (U+2029)
delimited-comment:
"/*" delimited-comment-section* "*"+ "/"
delimited-comment-section:
not-asterisk
"*"+ not-slash
not-asterisk:
Any Unicode character except *
not-slash:
Any Unicode character except /
token:
identifier
keyword
integer-literal
real-literal
character-literal
string-literal
operator-or-punctuator
unicode-character-escape-sequence:
"u" hex-digit hex-digit hex-digit hex-digit
"U" hex-digit hex-digit hex-digit hex-digit hex-digit hex-digit hex-digit hex-digit
identifier:
available-identifier
"@" identifier-or-keyword
available-identifier:
An identifier-or-keyword that is not a keyword
identifier-or-keyword:
identifier-start-character identifier-part-character*
identifier-start-character:
letter-character
"_"
identifier-part-character:
letter-character
decimal-digit-character
connecting-character
combining-character
formatting-character
letter-character:
A Unicode character of classes Lu, Ll, Lt, Lm, Lo, or Nl
A unicode-character-escape-sequence representing a character of classes Lu, Ll, Lt, Lm, Lo, or Nl
combining-character:
A Unicode character of classes Mn or Mc
A unicode-character-escape-sequence representing a character of classes Mn or Mc
decimal-digit-character:
A Unicode character of the class Nd
A unicode-character-escape-sequence representing a character of the class Nd
connecting-character:
A Unicode character of the class Pc
A unicode-character-escape-sequence representing a character of the class Pc
formatting-character:
A Unicode character of the class Cf
A unicode-character-escape-sequence representing a character of the class Cf
keyword:
"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"
literal:
boolean-literal
integer-literal
real-literal
character-literal
string-literal
null-literal
boolean-literal:
"true"
"false"
integer-literal:
decimal-digit+ integer-type-suffix?
"0x" hex-digit+ integer-type-suffix?
"0X" hex-digit+ integer-type-suffix?
decimal-digit:
"0"
"1"
"2"
"3"
"4"
"5"
"6"
"7"
"8"
"9"
integer-type-suffix:
"U"
"u"
"L"
"l"
"UL"
"Ul"
"uL"
"ul"
"LU"
"Lu"
"lU"
"lu"
hex-digit:
"0"
"1"
"2"
"3"
"4"
"5"
"6"
"7"
"8"
"9"
"A"
"B"
"C"
"D"
"E"
"F"
"a"
"b"
"c"
"d"
"e"
"f"
real-literal:
decimal-digit* "." decimal-digit+ exponent-part? real-type-suffix?
decimal-digit+ exponent-part real-type-suffix?
decimal-digit+ real-type-suffix
exponent-part:
"e" sign? decimal-digit+
"E" sign? decimal-digit+
sign:
"+"
"-"
real-type-suffix:
"F"
"f"
"D"
"d"
"M"
"m"
character-literal:
"'" character "'"
character:
single-character
"\" escape-sequence
escape-sequence:
"'"
'"'
"\"
"0"
"a"
"b"
"f"
"n"
"r"
"t"
"v"
hexadecimal-escape-sequence
unicode-character-escape-sequence
single-character:
Any character except ' (U+0027), \ (U+005C), and new-line-character
hexadecimal-escape-sequence:
"x" hex-digit ( hex-digit ( hex-digit hex-digit? )? )?
string-literal:
'"' regular-string-character* '"'
'@"' verbatim-string-character* '"'
regular-string-character:
single-regular-string-literal-character
"\" escape-sequence
verbatim-string-character:
single-verbatim-string-literal-character
quote-escape-sequence
single-regular-string-literal-character:
Any character except " (U+0022), \ (U+005C), and new-line-character
single-verbatim-string-literal-character:
Any character except "
quote-escape-sequence:
'""'
null-literal:
"null"
operator-or-punctuator:
"{"
"}"
"["
"]"
"("
")"
"."
","
":"
";"
"+"
"-"
"*"
"/"
"%"
"&"
"|"
"^"
"!"
"~"
"="
"<"
">"
"?"
"++"
"--"
"&&"
"||"
"<<"
">>"
"=="
"!="
"<="
">="
"+="
"-="
"*="
"/="
"%="
"&="
"|="
"^="
"<<="
">>="
"->"
pp-directive:
pp-declaration
pp-conditional
pp-line
pp-diagnostic
pp-region
pp-new-line:
whitespace? single-line-comment? new-line
conditional-symbol:
Any identifier-or-keyword except true or false
pp-expression:
whitespace? pp-or-expression whitespace?
pp-or-expression:
pp-and-expression
pp-or-expression whitespace? "||" whitespace? pp-and-expression
pp-and-expression:
pp-equality-expression
pp-and-expression whitespace? "&&" whitespace? pp-equality-expression
pp-equality-expression:
pp-unary-expression
pp-equality-expression whitespace? "==" whitespace? pp-unary-expression
pp-equality-expression whitespace? "!=" whitespace? pp-unary-expression
pp-unary-expression:
pp-primary-expression
"!" whitespace? pp-unary-expression
pp-primary-expression:
"true"
"false"
conditional-symbol
"(" whitespace? pp-expression whitespace? ")"
pp-declaration:
whitespace? "#" whitespace? "define" whitespace conditional-symbol pp-new-line
whitespace? "#" whitespace? "undef" whitespace conditional-symbol pp-new-line
pp-conditional:
pp-if-section pp-elif-sections? pp-else-section? pp-endif
pp-if-section:
whitespace? "#" whitespace? "if" whitespace pp-expression pp-new-line conditional-section?
pp-elif-sections:
pp-elif-section
pp-elif-sections pp-elif-section
pp-elif-section:
whitespace? "#" whitespace? "elif" whitespace pp-expression pp-new-line conditional-section?
pp-else-section:
whitespace? "#" whitespace? "else" pp-new-line conditional-section?
pp-endif:
whitespace? "#" whitespace? "endif" pp-new-line
conditional-section:
input-section-part+
skipped-section-part+
skipped-section-part:
skipped-characters? new-line
pp-directive
skipped-characters:
whitespace? not-number-sign input-character*
not-number-sign:
Any input-character except #
pp-line:
whitespace? "#" whitespace? "line" whitespace? line-indicator pp-new-line
line-indicator:
decimal-digit+ whitespace file-name
decimal-digit+
"default"
file-name:
'"' file-name-characters '"'
file-name-characters:
file-name-character
file-name-characters file-name-character
file-name-character:
Any character except " (U+0022), and new-line
pp-diagnostic:
whitespace? "#" whitespace? "error" whitespace? pp-message
whitespace? "#" whitespace? "warning" whitespace? pp-message
pp-message:
input-character* new-line
pp-region:
pp-start-region conditional-section? pp-end-region
pp-start-region:
whitespace? "#" whitespace? "region" whitespace? pp-message
pp-end-region:
whitespace? "#" whitespace? "endregion" whitespace? pp-message
compilation-unit:
using-directive* global-attributes namespace-member-declaration*
type:
non-array-type rank-specifier*
integral-type:
"sbyte"
"byte"
"short"
"ushort"
"int"
"uint"
"long"
"ulong"
"char"
array-type:
non-array-type rank-specifier+
non-array-type:
qualified-identifier
built-in-type
built-in-type:
integral-type
built-in-class-type
"bool"
"decimal"
"float"
"double"
rank-specifier:
"[" ","* "]"
argument-list:
{ argument "," } *
argument:
ref-or-out? expression
ref-or-out:
"ref"
"out"
primary-expression:
"new" non-array-type "[" expression-list "]" rank-specifier* array-initializer?
"new" array-type array-initializer
literal
identifier
"(" expression ")"
primary-expression "." identifier
predefined-type "." identifier
primary-expression "(" argument-list ")"
primary-expression "[" expression-list "]"
"this"
"base" "." identifier
"base" "[" expression-list "]"
primary-expression increment-decrement
"new" type "(" argument-list ")"
"typeof" "(" type-or-void ")"
"checked" "(" expression ")"
"unchecked" "(" expression ")"
increment-decrement:
"++"
"--"
type-or-void:
type
"void"
predefined-type:
"bool"
"byte"
"char"
"decimal"
"double"
"float"
"int"
"long"
"object"
"sbyte"
"short"
"string"
"uint"
"ulong"
"ushort"
expression-list:
{ expression "," } +
unary-expression:
expression-unary-operator unary-expression
"(" type ")" unary-expression
primary-expression
expression-unary-operator:
plus
minus
increment-decrement
"!"
"~"
"*"
assignment-operator:
"="
"+="
"-="
"*="
"/="
"%="
"&="
"|="
"^="
"<<="
">>="
expression:
expression "?" expression ":" expression
expression "||" expression
expression "&&" expression
expression bar expression
expression "^" expression
expression ampersand expression
expression expression-equality-operator expression
expression expression-relational-operator expression
expression "is" built-in-type
expression expression-shift-operator expression
expression plus expression
expression minus expression
expression "*" expression
expression "/" expression
expression "%" expression
unary-expression
unary-expression assignment-operator expression
bar:
"|"
ampersand:
"&"
expression-equality-operator:
"=="
"!="
expression-relational-operator:
less-than
greater-than
"<="
">="
"is"
"as"
expression-shift-operator:
"<<"
">>"
plus:
"+"
minus:
"-"
statement:
labeled-statement
declaration-statement
embedded-statement
embedded-statement:
maybe-empty-block
statement-expression ";"
selection-statement
iteration-statement
jump-statement
try-statement
"checked" block
"unchecked" block
lock-statement
using-statement
maybe-empty-block:
"{" statement* "}"
";"
block:
"{" statement* "}"
labeled-statement:
identifier ":" statement
declaration-statement:
local-variable-declaration ";"
local-constant-declaration ";"
local-variable-declaration:
type { variable-declarator "," } +
local-constant-declaration:
"const" type { constant-declarator "," } +
constant-declarator:
identifier "=" expression
statement-expression:
primary-expression "(" argument-list ")"
"new" type "(" argument-list ")"
unary-expression assignment-operator expression
primary-expression increment-decrement
increment-decrement primary-expression
selection-statement:
if-statement
switch-statement
if-statement:
"if" "(" expression ")" embedded-statement else-part?
else-part:
"else" embedded-statement
switch-statement:
"switch" "(" expression ")" "{" switch-section* "}"
switch-section:
switch-label+ statement+
switch-label:
"case" expression ":"
"default" ":"
iteration-statement:
while-statement
do-statement
for-statement
foreach-statement
while-statement:
"while" "(" expression ")" embedded-statement
do-statement:
"do" embedded-statement "while" "(" expression ")" ";"
for-statement:
"for" "(" for-initializer? ";" expression? ";" statement-expression-list? ")" embedded-statement
for-initializer:
local-variable-declaration
statement-expression-list
statement-expression-list:
{ statement-expression "," } +
foreach-statement:
"foreach" "(" type identifier "in" expression ")" embedded-statement
jump-statement:
break-statement
continue-statement
goto-statement
return-statement
throw-statement
break-statement:
"break" ";"
continue-statement:
"continue" ";"
goto-statement:
"goto" identifier ";"
"goto" "case" expression ";"
"goto" "default" ";"
return-statement:
"return" expression? ";"
throw-statement:
"throw" expression? ";"
try-statement:
"try" block catch-clauses finally-clause?
"try" block finally-clause
catch-clauses:
specific-catch-clause+ general-catch-clause?
specific-catch-clause* general-catch-clause
specific-catch-clause:
"catch" "(" built-in-class-type identifier? ")" block
"catch" "(" qualified-identifier identifier? ")" block
built-in-class-type:
"object"
"string"
general-catch-clause:
"catch" block
finally-clause:
"finally" block
lock-statement:
"lock" "(" expression ")" embedded-statement
using-statement:
"using" "(" resource-acquisition ")" embedded-statement
resource-acquisition:
local-variable-declaration
expression
namespace-declaration:
"namespace" qualified-identifier namespace-body ";"?
qualified-identifier:
{ identifier "." } +
namespace-body:
"{" using-directive* namespace-member-declaration* "}"
using-directive:
"using" ( identifier "=" )? qualified-identifier ";"
namespace-member-declaration:
namespace-declaration
type-declaration
type-declaration:
class-declaration
struct-declaration
interface-declaration
enum-declaration
delegate-declaration
class-declaration:
attributes class-modifier* "class" identifier class-base? class-body ";"?
class-modifier:
"new"
"public"
"protected"
"internal"
"private"
"abstract"
"sealed"
class-base:
":" qualified-identifier-list
":" built-in-class-type ( "," qualified-identifier-list )?
qualified-identifier-list:
{ qualified-identifier "," } +
class-body:
"{" class-member-declaration* "}"
class-member-declaration:
constant-declaration
field-declaration
method-declaration
property-declaration
event-declaration
indexer-declaration
operator-declaration
constructor-declaration
destructor-declaration
static-constructor-declaration
type-declaration
constant-declaration:
attributes constant-modifier* "const" type { constant-declarator "," } + ";"
constant-modifier:
"new"
"public"
"protected"
"internal"
"private"
constant-declarator:
field-declaration:
attributes field-modifier* type { variable-declarator "," } + ";"
field-modifier:
"new"
"public"
"protected"
"internal"
"private"
"static"
"readonly"
"volatile"
variable-declarator:
identifier
identifier "=" variable-initializer
variable-initializer:
expression
array-initializer
method-declaration:
method-header maybe-empty-block
method-header:
attributes method-modifier* type-or-void qualified-identifier "(" formal-parameter-list? ")"
method-modifier:
"new"
"public"
"protected"
"internal"
"private"
"static"
"virtual"
"sealed"
"override"
"abstract"
"extern"
formal-parameter-list:
fixed-parameters
fixed-parameters "," parameter-array
parameter-array
fixed-parameters:
{ fixed-parameter "," } +
fixed-parameter:
attributes parameter-modifier? type identifier
parameter-modifier:
"ref"
"out"
parameter-array:
attributes "params" array-type identifier
property-declaration:
attributes property-modifier* type qualified-identifier "{" accessor-declarations "}"
property-modifier:
"new"
"public"
"protected"
"internal"
"private"
"static"
"virtual"
"sealed"
"override"
"abstract"
"extern"
accessor-declarations:
get-accessor-declaration set-accessor-declaration?
set-accessor-declaration get-accessor-declaration?
get-accessor-declaration:
attributes "get" maybe-empty-block
set-accessor-declaration:
attributes "set" maybe-empty-block
event-declaration:
attributes event-modifier* "event" type { variable-declarator "," } + ";"
attributes event-modifier* "event" type qualified-identifier "{" event-accessor-declarations "}"
event-modifier:
"new"
"public"
"protected"
"internal"
"private"
"static"
"virtual"
"sealed"
"override"
"abstract"
"extern"
event-accessor-declarations:
add-accessor-declaration remove-accessor-declaration
remove-accessor-declaration add-accessor-declaration
add-accessor-declaration:
attributes "add" block
remove-accessor-declaration:
attributes "remove" block
indexer-declaration:
attributes indexer-modifier* indexer-declarator "{" accessor-declarations "}"
indexer-modifier:
"new"
"public"
"protected"
"internal"
"private"
"virtual"
"sealed"
"override"
"abstract"
"extern"
indexer-declarator:
type "this" "[" formal-parameter-list "]"
type qualified-identifier "." "this" "[" formal-parameter-list "]"
operator-declaration:
attributes operator-modifier+ operator-declarator maybe-empty-block
operator-modifier:
"public"
"static"
"extern"
operator-declarator:
unary-operator-declarator
binary-operator-declarator
conversion-operator-declarator
unary-operator-declarator:
type "operator" overloadable-unary-operator "(" type identifier ")"
overloadable-unary-operator:
plus
minus
increment-decrement
"!"
"~"
"true"
"false"
binary-operator-declarator:
type "operator" overloadable-binary-operator "(" type identifier "," type identifier ")"
overloadable-binary-operator:
plus
minus
"*"
"/"
"%"
ampersand
bar
"^"
"<<"
">>"
"=="
"!="
greater-than
less-than
">="
"<="
greater-than:
">"
less-than:
"<"
conversion-operator-declarator:
conversion-kind "operator" type "(" type identifier ")"
conversion-kind:
"implicit"
"explicit"
constructor-declaration:
attributes constructor-modifier* constructor-declarator maybe-empty-block
constructor-modifier:
"public"
"protected"
"internal"
"private"
"extern"
constructor-declarator:
identifier "(" formal-parameter-list? ")" constructor-initializer?
constructor-initializer:
":" "base" "(" argument-list ")"
":" "this" "(" argument-list ")"
static-constructor-declaration:
attributes static-constructor-modifiers identifier "(" ")" maybe-empty-block
static-constructor-modifiers:
"extern"? "static"
"static" "extern"
destructor-declaration:
attributes "extern"? "~" identifier "(" ")" maybe-empty-block
struct-declaration:
attributes struct-modifier* "struct" identifier ( ":" qualified-identifier-list )? struct-body ";"?
struct-modifier:
"new"
"public"
"protected"
"internal"
"private"
struct-body:
"{" struct-member-declaration* "}"
struct-member-declarations:
struct-member-declaration
struct-member-declarations struct-member-declaration
struct-member-declaration:
constant-declaration
field-declaration
method-declaration
property-declaration
event-declaration
indexer-declaration
operator-declaration
constructor-declaration
static-constructor-declaration
type-declaration
array-type:
non-array-type:
rank-specifier:
array-initializer:
"{" "}"
"{" { variable-initializer "," } + ","? "}"
variable-initializer:
interface-declaration:
attributes interface-modifier* "interface" identifier ( ":" qualified-identifier-list )? interface-body ";"?
interface-modifier:
"new"
"public"
"protected"
"internal"
"private"
interface-body:
"{" interface-member-declaration* "}"
interface-member-declaration:
interface-method-declaration
interface-property-declaration
interface-event-declaration
interface-indexer-declaration
interface-method-declaration:
attributes "new"? type-or-void identifier "(" formal-parameter-list? ")" ";"
interface-property-declaration:
attributes "new"? type identifier "{" interface-accessors "}"
interface-accessors:
attributes "get" ";" ( attributes "set" ";" )?
attributes "set" ";" ( attributes "get" ";" )?
interface-event-declaration:
attributes "new"? "event" type identifier ";"
interface-indexer-declaration:
attributes "new"? type "this" "[" formal-parameter-list "]" "{" interface-accessors "}"
enum-declaration:
attributes enum-modifier* "enum" identifier ( ":" integral-type )? enum-body ";"?
enum-body:
"{" "}"
"{" { enum-member-declaration "," } + ","? "}"
enum-modifier:
"new"
"public"
"protected"
"internal"
"private"
enum-member-declaration:
attributes identifier ( "=" expression )?
delegate-declaration:
attributes delegate-modifier* "delegate" type-or-void identifier "(" formal-parameter-list? ")" ";"
delegate-modifier:
"new"
"public"
"protected"
"internal"
"private"
global-attributes:
global-attribute-section*
global-attribute-section:
"[" "assembly" ":" attribute-list ","? "]"
attributes:
attribute-section*
attribute-section:
"[" ( attribute-target ":" )? attribute-list ","? "]"
attribute-target:
"field"
"event"
"method"
"module"
"param"
"property"
"return"
"type"
attribute-list:
{ attribute "," } +
attribute:
attribute-name attribute-arguments?
attribute-name:
qualified-identifier
attribute-arguments:
"(" expression-list? ")"
