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


// A.1 Lexical grammar


input:
    input-section-part*

input-section-part:
    input-element* new-line
    pp-directive

input-element:
    whitespace
    comment
    token

// A.1.1 Line terminators


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)

// A.1.2 White space


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)

// A.1.3 Comments


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 /

// A.1.4 Tokens


token:
    identifier
    keyword
    integer-literal
    real-literal
    character-literal
    string-literal
    operator-or-punctuator

// A.1.5 Unicode character escape sequences


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

// A.1.6 Identifiers


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

// A.1.7 Keywords


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"

// A.1.8 Literals


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"

// A.1.9 Operators and punctuators


operator-or-punctuator:
    "{"
    "}"
    "["
    "]"
    "("
    ")"
    "."
    ","
    ":"
    ";"
    "+"
    "-"
    "*"
    "/"
    "%"
    "&"
    "|"
    "^"
    "!"
    "~"
    "="
    "<"
    ">"
    "?"
    "++"
    "--"
    "&&"
    "||"
    "<<"
    ">>"
    "=="
    "!="
    "<="
    ">="
    "+="
    "-="
    "*="
    "/="
    "%="
    "&="
    "|="
    "^="
    "<<="
    ">>="
    "->"

// A.1.10 Pre-processing directives


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

// A.2 Syntactic grammar


// A.2.1 Basic concepts


compilation-unit:
    using-directive* global-attributes namespace-member-declaration*

// A.2.2 Types


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:
    "[" ","* "]"

// A.2.3 Variables


// A.2.4 Expressions


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:
    "-"

// A.2.5 Statements


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

// A.2.6 Classes


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

// A.2.7 Structs


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

// A.2.8 Arrays


array-type:

non-array-type:

rank-specifier:

array-initializer:
    "{" "}"
    "{" { variable-initializer "," } + ","? "}"

variable-initializer:

// A.2.9 Interfaces


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 "}"

// A.2.10 Enums


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 )?

// A.2.11 Delegates


delegate-declaration:
    attributes delegate-modifier* "delegate" type-or-void identifier "(" formal-parameter-list? ")" ";"

delegate-modifier:
    "new"
    "public"
    "protected"
    "internal"
    "private"

// A.2.12 Attributes


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? ")"

Valid XHTML 1.0 StrictValid CSS!