目錄
BNF詳細的語法定義
在雙引號中的字("word")代表着這些字符本身。而double_quote用來代表雙引號。
在雙引號外的字(有可能有下劃線)代表着語法部分。
尖括號( < > )內包含的爲必選項。
方括號( [ ] )內包含的爲可選項。
大括號( { } )內包含的爲可重複0至無數次的項。
豎線( | )表示在其左右兩邊任選一項,相當於"OR"的意思。
::= 是“被定義爲”的意思。
這是用BNF來定義的Java語言中的For語句的實例:
FOR_STATEMENT ::=
"for" "(" ( variable_declaration |
( expression ";" ) | ";" )
[ expression ] ";"
[ expression ] ";"
")" statement
這是Oracle packages的BNF定義:
package_body ::= "package" package_name "is"
package_obj_body
[ "begin" seq_of_statements ]
"end" [ package_name ] ";"
package_obj_body ::= variable_declaration
| subtype_declaration
| cursor_declaration
| cursor_body
| exception_declaration
| record_declaration
| plsql_table_declaration
| procedure_body
| function_body
procedure_body ::= "procedure" procedure_name
[ "(" argument { "," argument } ")" ]
"return" return_type
"is"
[ "declare" declare_spec ";" { declare_spec ";" } ]
"begin"
seq_of_statements
[ "exception" exception_handler ]
"end" [ procedure_name ] ";"
statement ::= comment
| assignment_statement
| exit_statement
| goto_statement
| if_statement
| loop_statement
| null_statement
| raise_statement
| return_statement
| sql_statement
| plsql_block
這是用BNF來定義的BNF本身的例子:
syntax ::=
rule ::= identifier "::=" expression
expression ::= term { "|" term }
term ::= factor
factor ::= identifier |
quoted_symbol |
"(" expression ")" |
"[" expression "]" |
"{" expression "}"
identifier ::= letter { letter | digit }
quoted_symbol ::= """ """
擴展的巴科斯範式 Augmented BNF
ABNF
ABNF:
rule = definition ; comment CR LF
1. rule不需要用尖括號括起來,與BNF不同
2. 不區分大小寫
3. 如果期望明確定義,則使用%d97代表a
4. 終結符就是可以直接出現在語言中的符號,非終結符就是語言中某些抽象的概念。
5. '::=' 意味着必須被替換
Augmented BNF for Syntax Specifications: ABNF
Status of This Memo
This document specifies an Internet standards track protocol for the
Internet community, and requests discussion and suggestions for
improvements. Please refer to the current edition of the "Internet
Official Protocol Standards" (STD 1) for the standardization state
and status of this protocol. Distribution of this memo is unlimited.
Abstract
Internet technical specifications often need to define a formal
syntax. Over the years, a modified version of Backus-Naur Form
(BNF), called Augmented BNF (ABNF), has been popular among many
Internet specifications. The current specification documents ABNF.
It balances compactness and simplicity with reasonable
representational power. The differences between standard BNF and
ABNF involve naming rules, repetition, alternatives, order-
independence, and value ranges. This specification also supplies
additional rule definitions and encoding for a core lexical analyzer
of the type common to several Internet specifications.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Rule Definition . . . . . . . . . . . . . . . . . . . . . . . 3
2.1. Rule Naming . . . . . . . . . . . . . . . . . . . . . . . 3
2.2. Rule Form . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3. Terminal Values . . . . . . . . . . . . . . . . . . . . . 4
2.4. External Encodings . . . . . . . . . . . . . . . . . . . . 6
3. Operators . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.1. Concatenation: Rule1 Rule2 . . . . . . . . . . . . . . . 6
3.2. Alternatives: Rule1 / Rule2 . . . . . . . . . . . . . . . 7
3.3. Incremental Alternatives: Rule1 =/ Rule2 . . . . . . . . . 7
3.4. Value Range Alternatives: %c##-## . . . . . . . . . . . . 8
3.5. Sequence Group: (Rule1 Rule2) . . . . . . . . . . . . . . 8
3.6. Variable Repetition: *Rule . . . . . . . . . . . . . . . 9
3.7. Specific Repetition: nRule . . . . . . . . . . . . . . . 9
3.8. Optional Sequence: [RULE] . . . . . . . . . . . . . . . . 9
3.9. Comment: ; Comment . . . . . . . . . . . . . . . . . . . 9
3.10. Operator Precedence . . . . . . . . . . . . . . . . . . . 10
4. ABNF Definition of ABNF . . . . . . . . . . . . . . . . . . . 10
5. Security Considerations . . . . . . . . . . . . . . . . . . . 12
6. References . . . . . . . . . . . . . . . . . . . . . . . . . . 12
6.1. Normative References . . . . . . . . . . . . . . . . . . . 12
6.2. Informative References . . . . . . . . . . . . . . . . . . 12
Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 13
Appendix B. Core ABNF of ABNF . . . . . . . . . . . . . . . . . . 13
B.1. Core Rules . . . . . . . . . . . . . . . . . . . . . . . . 13
B.2. Common Encoding . . . . . . . . . . . . . . . . . . . . . 15
1. Introduction
Internet technical specifications often need to define a formal
syntax and are free to employ whatever notation their authors deem
useful. Over the years, a modified version of Backus-Naur Form
(BNF), called Augmented BNF (ABNF), has been popular among many
Internet specifications. It balances compactness and simplicity with
reasonable representational power. In the early days of the Arpanet,
each specification contained its own definition of ABNF. This
included the email specifications, [RFC733] and then [RFC822], which
came to be the common citations for defining ABNF. The current
document separates those definitions to permit selective reference.
Predictably, it also provides some modifications and enhancements.
The differences between standard BNF and ABNF involve naming rules,
repetition, alternatives, order-independence, and value ranges.
Appendix B supplies rule definitions and encoding for a core lexical
analyzer of the type common to several Internet specifications. It
is provided as a convenience and is otherwise separate from the meta
language defined in the body of this document, and separate from its
formal status.
2. Rule Definition
2.1. Rule Naming
The name of a rule is simply the name itself, that is, a sequence of
characters, beginning with an alphabetic character, and followed by a
combination of alphabetics, digits, and hyphens (dashes).
NOTE:
Rule names are case insensitive.
The names <rulename>, <Rulename>, <RULENAME>, and <rUlENamE> all
refer to the same rule.
Unlike original BNF, angle brackets ("<", ">") are not required.
However, angle brackets may be used around a rule name whenever their
presence facilitates in discerning the use of a rule name. This is
typically restricted to rule name references in free-form prose, or
to distinguish partial rules that combine into a string not separated
by white space, such as shown in the discussion about repetition,
below.
2.2. Rule Form
A rule is defined by the following sequence:
name = elements crlf
where <name> is the name of the rule, <elements> is one or more rule
names or terminal specifications, and <crlf> is the end-of-line
indicator (carriage return followed by line feed). The equal sign
separates the name from the definition of the rule. The elements
form a sequence of one or more rule names and/or value definitions,
combined according to the various operators defined in this document,
such as alternative and repetition.
For visual ease, rule definitions are left aligned. When a rule
requires multiple lines, the continuation lines are indented. The
left alignment and indentation are relative to the first lines of the
ABNF rules and need not match the left margin of the document.
2.3. Terminal Values
Rules resolve into a string of terminal values, sometimes called
characters. In ABNF, a character is merely a non-negative integer.
In certain contexts, a specific mapping (encoding) of values into a
character set (such as ASCII) will be specified.
Terminals are specified by one or more numeric characters, with the
base interpretation of those characters indicated explicitly. The
following bases are currently defined:
b = binary
d = decimal
x = hexadecimal
Hence:
CR = %d13
CR = %x0D
respectively specify the decimal and hexadecimal representation of
[US-ASCII] for carriage return.
A concatenated string of such values is specified compactly, using a
period (".") to indicate a separation of characters within that
value. Hence:
CRLF = %d13.10
ABNF permits the specification of literal text strings directly,
enclosed in quotation marks. Hence:
command = "command string"
Literal text strings are interpreted as a concatenated set of
printable characters.
NOTE:
ABNF strings are case insensitive and the character set for these
strings is US-ASCII.
Hence:
rulename = "abc"
and:
rulename = "aBc"
will match "abc", "Abc", "aBc", "abC", "ABc", "aBC", "AbC", and
"ABC".
To specify a rule that is case sensitive, specify the characters
individually.
For example:
rulename = %d97 %d98 %d99
or
rulename = %d97.98.99
will match only the string that comprises only the lowercase
characters, abc.
2.4. External Encodings
External representations of terminal value characters will vary
according to constraints in the storage or transmission environment.
Hence, the same ABNF-based grammar may have multiple external
encodings, such as one for a 7-bit US-ASCII environment, another for
a binary octet environment, and still a different one when 16-bit
Unicode is used. Encoding details are beyond the scope of ABNF,
although Appendix B provides definitions for a 7-bit US-ASCII
environment as has been common to much of the Internet.
By separating external encoding from the syntax, it is intended that
alternate encoding environments can be used for the same syntax.
3. Operators
3.1. Concatenation:
Rule1 Rule2
A rule can define a simple, ordered string of values (i.e., a
concatenation of contiguous characters) by listing a sequence of rule
names. For example:
foo = %x61 ; a
bar = %x62 ; b
mumble = foo bar foo
So that the rule <mumble> matches the lowercase string "aba".
Linear white space: Concatenation is at the core of the ABNF parsing
model. A string of contiguous characters (values) is parsed
according to the rules defined in ABNF. For Internet specifications,
there is some history of permitting linear white space (space and
horizontal tab) to be freely and implicitly interspersed around major
constructs, such as delimiting special characters or atomic strings.
NOTE:
This specification for ABNF does not provide for implicit
specification of linear white space.
Any grammar that wishes to permit linear white space around
delimiters or string segments must specify it explicitly. It is
often useful to provide for such white space in "core" rules that are
then used variously among higher-level rules. The "core" rules might
be formed into a lexical analyzer or simply be part of the main
ruleset.
3.2. Alternatives:
Rule1 / Rule2
Elements separated by a forward slash ("/") are alternatives.
Therefore,
foo / bar
will accept <foo> or <bar>.
NOTE:
A quoted string containing alphabetic characters is a special form
for specifying alternative characters and is interpreted as a non-
terminal representing the set of combinatorial strings with the
contained characters, in the specified order but with any mixture
of upper- and lowercase.
3.3. Incremental Alternatives: Rule1 =/ Rule2
It is sometimes convenient to specify a list of alternatives in
fragments. That is, an initial rule may match one or more
alternatives, with later rule definitions adding to the set of
alternatives. This is particularly useful for otherwise independent
specifications that derive from the same parent ruleset, such as
often occurs with parameter lists. ABNF permits this incremental
definition through the construct:
oldrule =/ additional-alternatives
So that the ruleset
ruleset = alt1 / alt2
ruleset =/ alt3
ruleset =/ alt4 / alt5
is the same as specifying
ruleset = alt1 / alt2 / alt3 / alt4 / alt5
3.4. Value Range Alternatives:
%c##-##
A range of alternative numeric values can be specified compactly,
using a dash ("-") to indicate the range of alternative values.
Hence:
DIGIT = %x30-39
is equivalent to:
DIGIT = "0" / "1" / "2" / "3" / "4" / "5" / "6" /
"7" / "8" / "9"
Concatenated numeric values and numeric value ranges cannot be
specified in the same string. A numeric value may use the dotted
notation for concatenation or it may use the dash notation to specify
one value range. Hence, to specify one printable character between
end-of-line sequences, the specification could be:
char-line = %x0D.0A %x20-7E %x0D.0A
3.5. Sequence Group:
(Rule1 Rule2)
Elements enclosed in parentheses are treated as a single element,
whose contents are strictly ordered. Thus,
elem (foo / bar) blat
matches (elem foo blat) or (elem bar blat), and
elem foo / bar blat
matches (elem foo) or (bar blat).
NOTE:
It is strongly advised that grouping notation be used, rather than
relying on the proper reading of "bare" alternations, when
alternatives consist of multiple rule names or literals.
Hence, it is recommended that the following form be used:
(elem foo) / (bar blat)
It will avoid misinterpretation by casual readers.
The sequence group notation is also used within free text to set off
an element sequence from the prose.
3.6. Variable Repetition:
*Rule
The operator "*" preceding an element indicates repetition. The full
form is:
<a>*<b>element
where <a> and <b> are optional decimal values, indicating at least
<a> and at most <b> occurrences of the element.
Default values are 0 and infinity so that *<element> allows any
number, including zero; 1*<element> requires at least one;
3*3<element> allows exactly 3; and 1*2<element> allows one or two.
3.7. Specific Repetition:
nRule
A rule of the form:
<n>element
is equivalent to
<n>*<n>element
That is, exactly <n> occurrences of <element>. Thus, 2DIGIT is a
2-digit number, and 3ALPHA is a string of three alphabetic
characters.
3.8. Optional Sequence:
[RULE]
Square brackets enclose an optional element sequence:
[foo bar]
is equivalent to
*1(foo bar).
3.9. Comment:
; Comment
A semicolon starts a comment that continues to the end of line. This
is a simple way of including useful notes in parallel with the
specifications.
3.10. Operator Precedence
The various mechanisms described above have the following precedence,
from highest (binding tightest) at the top, to lowest (loosest) at
the bottom:
Rule name, prose-val, Terminal value
Comment
Value range
Repetition
Grouping, Optional
Concatenation
Alternative
Use of the alternative operator, freely mixed with concatenations,
can be confusing.
Again, it is recommended that the grouping operator be used to
make explicit concatenation groups.
4. ABNF Definition of ABNF
NOTES:
1. This syntax requires a formatting of rules that is relatively
strict. Hence, the version of a ruleset included in a
specification might need preprocessing to ensure that it can
be interpreted by an ABNF parser.
2. This syntax uses the rules provided in Appendix B.
rulelist = 1*( rule / (*c-wsp c-nl) )
rule = rulename defined-as elements c-nl
; continues if next line starts
; with white space
rulename = ALPHA *(ALPHA / DIGIT / "-")
defined-as = *c-wsp ("=" / "=/") *c-wsp
; basic rules definition and
; incremental alternatives
elements = alternation *c-wsp
c-wsp = WSP / (c-nl WSP)
c-nl = comment / CRLF
; comment or newline
comment = ";" *(WSP / VCHAR) CRLF
alternation = concatenation
*(*c-wsp "/" *c-wsp concatenation)
concatenation = repetition *(1*c-wsp repetition)
repetition = [repeat] element
repeat = 1*DIGIT / (*DIGIT "*" *DIGIT)
element = rulename / group / option /
char-val / num-val / prose-val
group = "(" *c-wsp alternation *c-wsp ")"
option = "[" *c-wsp alternation *c-wsp "]"
char-val = DQUOTE *(%x20-21 / %x23-7E) DQUOTE
; quoted string of SP and VCHAR
; without DQUOTE
num-val = "%" (bin-val / dec-val / hex-val)
bin-val = "b" 1*BIT
[ 1*("." 1*BIT) / ("-" 1*BIT) ]
; series of concatenated bit values
; or single ONEOF range
dec-val = "d" 1*DIGIT
[ 1*("." 1*DIGIT) / ("-" 1*DIGIT) ]
hex-val = "x" 1*HEXDIG
[ 1*("." 1*HEXDIG) / ("-" 1*HEXDIG) ]
prose-val = "<" *(%x20-3D / %x3F-7E) ">"
; bracketed string of SP and VCHAR
; without angles
; prose description, to be used as
; last resort
5. Security Considerations
Security is truly believed to be irrelevant to this document.
6. References
6.1. Normative References
[US-ASCII] American National Standards Institute, "Coded Character
Set -- 7-bit American Standard Code for Information
Interchange", ANSI X3.4, 1986.
6.2. Informative References
[RFC733] Crocker, D., Vittal, J., Pogran, K., and D. Henderson,
"Standard for the format of ARPA network text messages",
RFC 733, November 1977.
[RFC822] Crocker, D., "Standard for the format of ARPA Internet
text messages", STD 11, RFC 822, August 1982.
Appendix A. Acknowledgements
The syntax for ABNF was originally specified in RFC 733. Ken L.
Harrenstien, of SRI International, was responsible for re-coding the
BNF into an Augmented BNF that makes the representation smaller and
easier to understand.
This recent project began as a simple effort to cull out the portion
of RFC 822 that has been repeatedly cited by non-email specification
writers, namely the description of Augmented BNF. Rather than simply
and blindly converting the existing text into a separate document,
the working group chose to give careful consideration to the
deficiencies, as well as benefits, of the existing specification and
related specifications made available over the last 15 years, and
therefore to pursue enhancement. This turned the project into
something rather more ambitious than was first intended.
Interestingly, the result is not massively different from that
original, although decisions, such as removing the list notation,
came as a surprise.
This "separated" version of the specification was part of the DRUMS
working group, with significant contributions from Jerome Abela,
Harald Alvestrand, Robert Elz, Roger Fajman, Aviva Garrett, Tom
Harsch, Dan Kohn, Bill McQuillan, Keith Moore, Chris Newman, Pete
Resnick, and Henning Schulzrinne.
Julian Reschke warrants a special thanks for converting the Draft
Standard version to XML source form.
Appendix B. Core ABNF of ABNF
This appendix contains some basic rules that are in common use.
Basic rules are in uppercase. Note that these rules are only valid
for ABNF encoded in 7-bit ASCII or in characters sets that are a
superset of 7-bit ASCII.
B.1. Core Rules
Certain basic rules are in uppercase, such as SP, HTAB, CRLF, DIGIT,
ALPHA, etc.
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
BIT = "0" / "1"
CHAR = %x01-7F
; any 7-bit US-ASCII character,
; excluding NUL
CR = %x0D
; carriage return
CRLF = CR LF
; Internet standard newline
CTL = %x00-1F / %x7F
; controls
DIGIT = %x30-39
; 0-9
DQUOTE = %x22
; " (Double Quote)
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
HTAB = %x09
; horizontal tab
LF = %x0A
; linefeed
LWSP = *(WSP / CRLF WSP)
; Use of this linear-white-space rule
; permits lines containing only white
; space that are no longer legal in
; mail headers and have caused
; interoperability problems in other
; contexts.
; Do not use when defining mail
; headers and use with caution in
; other contexts.
OCTET = %x00-FF
; 8 bits of data
SP = %x20
VCHAR = %x21-7E
; visible (printing) characters
WSP = SP / HTAB
; white space
B.2. Common Encoding
Externally, data are represented as "network virtual ASCII" (namely,
7-bit US-ASCII in an 8-bit field), with the high (8th) bit set to
zero. A string of values is in "network byte order", in which the
higher-valued bytes are represented on the left-hand side and are
sent over the network first.
C# BNF
This appendix contains summaries of the lexical and syntactic grammars found in the main document, and of the grammar extensions for unsafe code. Grammar productions appear here in the same order that they appear in the main document.
input:
input-sectionopt
input-section:
input-section-part
input-section input-section-part
input-section-part:
input-elementsopt new-line
pp-directive
input-elements:
input-element
input-elements input-element
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)
comment:
single-line-comment
delimited-comment
single-line-comment:
// input-charactersopt
input-characters:
input-character
input-characters 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-textopt asterisks /
delimited-comment-text:
delimited-comment-section
delimited-comment-text delimited-comment-section
delimited-comment-section:
/
asterisksopt not-slash-or-asterisk
asterisks:
*
asterisks *
not-slash-or-asterisk:
Any Unicode character except / or *
whitespace:
Any character with Unicode class Zs
Horizontal tab character (U+0009)
Vertical tab character (U+000B)
Form feed character (U+000C)
token:
identifier
keyword
integer-literal
real-literal
character-literal
string-literal
operator-or-punctuator
A.1.5 Unicode character escape sequences
unicode-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-charactersopt
identifier-start-character:
letter-character
_(the underscore character U+005F)
identifier-part-characters:
identifier-part-character
identifier-part-characters identifier-part-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-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-escape-sequence representing a character of classes Mn or Mc
decimal-digit-character:
A Unicode character of the class Nd
A unicode-escape-sequence representing a character of the class Nd
connecting-character:
A Unicode character of the class Pc
A unicode-escape-sequence representing a character of the class Pc
formatting-character:
A Unicode character of the class Cf
A unicode-escape-sequence representing a character of the class Cf
keyword: one of
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-integer-literal
hexadecimal-integer-literal
decimal-integer-literal:
decimal-digits integer-type-suffixopt
decimal-digits:
decimal-digit
decimal-digits decimal-digit
decimal-digit: one of
0 1 2 3 4 5 6 7 8 9
integer-type-suffix: one of
U u L l UL Ul uL ul LU Lu lU lu
hexadecimal-integer-literal:
0x hex-digits integer-type-suffixopt
0X hex-digits integer-type-suffixopt
hex-digits:
hex-digit
hex-digits hex-digit
hex-digit: one of
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-digits . decimal-digits exponent-partopt real-type-suffixopt
. decimal-digits exponent-partopt real-type-suffixopt
decimal-digits exponent-part real-type-suffixopt
decimal-digits real-type-suffix
exponent-part:
e signopt decimal-digits
E signopt decimal-digits
sign: one of
+ -
real-type-suffix: one of
F f D d M m
character-literal:
' character '
character:
single-character
simple-escape-sequence
hexadecimal-escape-sequence
unicode-escape-sequence
single-character:
Any character except ' (U+0027), \ (U+005C), and new-line-character
simple-escape-sequence: one of
\' \" \\ \0 \a \b \f \n \r \t \v
hexadecimal-escape-sequence:
\x hex-digit hex-digitopt hex-digitopt hex-digitopt
string-literal:
regular-string-literal
verbatim-string-literal
regular-string-literal:
" regular-string-literal-charactersopt"
regular-string-literal-characters:
regular-string-literal-character
regular-string-literal-characters regular-string-literal-character
regular-string-literal-character:
single-regular-string-literal-character
simple-escape-sequence
hexadecimal-escape-sequence
unicode-escape-sequence
single-regular-string-literal-character:
Any character except " (U+0022), \ (U+005C), and new-line-character
verbatim-string-literal:
@" verbatim-string-literal-charactersopt"
verbatim-string-literal-characters:
verbatim-string-literal-character
verbatim-string-literal-characters verbatim-string-literal-character
verbatim-string-literal-character:
single-verbatim-string-literal-character
quote-escape-sequence
single-verbatim-string-literal-character:
any character except "
quote-escape-sequence:
""
null-literal:
null
A.1.9 Operators and punctuators
operator-or-punctuator: one of
{ } [ ] ( ) . , : ;
+ - * / % & | ^ ! ~
= < > ? ?? :: ++ -- && ||
-> == != <= >= += -= *= /= %=
&= |= ^= << <<= =>
right-shift:
>|>
right-shift-assignment:
>|>=
A.1.10 Pre-processing directives
pp-directive:
pp-declaration
pp-conditional
pp-line
pp-diagnostic
pp-region
pp-pragma
conditional-symbol:
Any identifier-or-keyword except true or false
pp-expression:
whitespaceopt pp-or-expression whitespaceopt
pp-or-expression:
pp-and-expression
pp-or-expression whitespaceopt|| whitespaceopt pp-and-expression
pp-and-expression:
pp-equality-expression
pp-and-expression whitespaceopt&& whitespaceopt pp-equality-expression
pp-equality-expression:
pp-unary-expression
pp-equality-expression whitespaceopt== whitespaceopt pp-unary-expression
pp-equality-expression whitespaceopt!= whitespaceopt pp-unary-expression
pp-unary-expression:
pp-primary-expression
! whitespaceopt pp-unary-expression
pp-primary-expression:
true
false
conditional-symbol
( whitespaceopt pp-expression whitespaceopt)
pp-declaration:
whitespaceopt# whitespaceoptdefine whitespace conditional-symbol pp-new-line
whitespaceopt# whitespaceoptundef whitespace conditional-symbol pp-new-line
pp-new-line:
whitespaceopt single-line-commentopt new-line
pp-conditional:
pp-if-section pp-elif-sectionsopt pp-else-sectionopt pp-endif
pp-if-section:
whitespaceopt# whitespaceoptif whitespace pp-expression pp-new-line conditional-sectionopt
pp-elif-sections:
pp-elif-section
pp-elif-sections pp-elif-section
pp-elif-section:
whitespaceopt# whitespaceoptelif whitespace pp-expression pp-new-line conditional-sectionopt
pp-else-section:
whitespaceopt# whitespaceoptelse pp-new-line conditional-sectionopt
pp-endif:
whitespaceopt# whitespaceoptendif pp-new-line
conditional-section:
input-section
skipped-section
skipped-section:
skipped-section-part
skipped-section skipped-section-part
skipped-section-part:
skipped-charactersopt new-line
pp-directive
skipped-characters:
whitespaceopt not-number-sign input-charactersopt
not-number-sign:
Any input-character except #
pp-diagnostic:
whitespaceopt# whitespaceopterror pp-message
whitespaceopt# whitespaceoptwarning pp-message
pp-message:
new-line
whitespace input-charactersopt new-line
pp-region:
pp-start-region conditional-sectionopt pp-end-region
pp-start-region:
whitespaceopt# whitespaceoptregion pp-message
pp-end-region:
whitespaceopt# whitespaceoptendregion pp-message
pp-line:
whitespaceopt# whitespaceoptline whitespace line-indicator pp-new-line
line-indicator:
decimal-digits whitespace file-name
decimal-digits
default
hidden
file-name:
" file-name-characters "
file-name-characters:
file-name-character
file-name-characters file-name-character
file-name-character:
Any input-character except "
pp-pragma:
whitespaceopt# whitespaceoptpragma whitespace pragma-body pp-new-line
pragma-body:
pragma-warning-body
pragma-warning-body:
warning whitespace warning-action
warning whitespace warning-action whitespace warning-list
warning-action:
disable
restore
warning-list:
decimal-digits
warning-list whitespaceopt, whitespaceopt decimal-digits
namespace-name:
namespace-or-type-name
type-name:
namespace-or-type-name
namespace-or-type-name:
identifier type-argument-listopt
namespace-or-type-name . identifier type-argument-listopt
qualified-alias-member
type:
value-type
reference-type
type-parameter
value-type:
struct-type
enum-type
struct-type:
type-name
simple-type
nullable-type
simple-type:
numeric-type
bool
numeric-type:
integral-type
floating-point-type
decimal
integral-type:
sbyte
byte
short
ushort
int
uint
long
ulong
char
floating-point-type:
float
double
nullable-type:
non-nullable-value-type ?
non-nullable-value-type:
type
enum-type:
type-name
reference-type:
class-type
interface-type
array-type
delegate-type
class-type:
type-name
object
dynamic
string
interface-type:
type-name
rank-specifiers:
rank-specifier
rank-specifiers rank-specifier
rank-specifier:
[ dim-separatorsopt]
dim-separators:
,
dim-separators ,
delegate-type:
type-name
type-argument-list:
< type-arguments >
type-arguments:
type-argument
type-arguments , type-argument
type-argument:
type
type-parameter:
identifier
variable-reference:
expression
argument-list:
argument
argument-list , argument
argument:
argument-nameopt argument-value
argument-name:
identifier :
argument-value:
expression
ref variable-reference
out variable-reference
primary-expression:
primary-no-array-creation-expression
array-creation-expression
primary-no-array-creation-expression:
literal
simple-name
parenthesized-expression
member-access
invocation-expression
element-access
this-access
base-access
post-increment-expression
post-decrement-expression
object-creation-expression
delegate-creation-expression
anonymous-object-creation-expression
typeof-expression
checked-expression
unchecked-expression
default-value-expression
anonymous-method-expression
simple-name:
identifier type-argument-listopt
parenthesized-expression:
( expression )
member-access:
primary-expression . identifier type-argument-listopt
predefined-type . identifier type-argument-listopt
qualified-alias-member . identifier
predefined-type: one of
bool byte char decimal double float int long
object sbyte short string uint ulong ushort
invocation-expression:
primary-expression ( argument-listopt)
element-access:
primary-no-array-creation-expression [argument-list ]
this-access:
this
base-access:
base. identifier
base[argument-list ]
post-increment-expression:
primary-expression ++
post-decrement-expression:
primary-expression --
object-creation-expression:
new type ( argument-listopt) object-or-collection-initializeropt
new type object-or-collection-initializer
object-or-collection-initializer:
object-initializer
collection-initializer
object-initializer:
{ member-initializer-listopt}
{ member-initializer-list ,}
member-initializer-list:
member-initializer
member-initializer-list , member-initializer
member-initializer:
identifier = initializer-value
initializer-value:
expression
object-or-collection-initializer
collection-initializer:
{ element-initializer-list }
{ element-initializer-list ,}
element-initializer-list:
element-initializer
element-initializer-list , element-initializer
element-initializer:
non-assignment-expression
{ expression-list }
expression-list:
expression
expression-list , expression
array-creation-expression:
new non-array-type [ expression-list ] rank-specifiersopt array-initializeropt
new array-type array-initializer
new rank-specifier array-initializer
delegate-creation-expression:
new delegate-type ( expression )
anonymous-object-creation-expression:
new anonymous-object-initializer
anonymous-object-initializer:
{ member-declarator-listopt}
{ member-declarator-list ,}
member-declarator-list:
member-declarator
member-declarator-list , member-declarator
member-declarator:
simple-name
member-access
identifier = expression
typeof-expression:
typeof( type )
typeof( unbound-type-name )
typeof ( void )
unbound-type-name:
identifier generic-dimension-specifieropt
identifier :: identifier generic-dimension-specifieropt
unbound-type-name . identifier generic-dimension-specifieropt
generic-dimension-specifier:
< commasopt>
commas:
,
commas ,
checked-expression:
checked( expression )
unchecked-expression:
unchecked( expression )
default-value-expression:
default( type )
unary-expression:
primary-expression
+ unary-expression
- unary-expression
! unary-expression
~ unary-expression
pre-increment-expression
pre-decrement-expression
cast-expression
pre-increment-expression:
++ unary-expression
pre-decrement-expression:
-- unary-expression
cast-expression:
( type ) unary-expression
multiplicative-expression:
unary-expression
multiplicative-expression * unary-expression
multiplicative-expression / unary-expression
multiplicative-expression % unary-expression
additive-expression:
multiplicative-expression
additive-expression + multiplicative-expression
additive-expression – multiplicative-expression
shift-expression:
additive-expression
shift-expression << additive-expression
shift-expression right-shift additive-expression
relational-expression:
shift-expression
relational-expression < shift-expression
relational-expression > shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression
relational-expression is type
relational-expression as type
equality-expression:
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression
and-expression:
equality-expression
and-expression & equality-expression
exclusive-or-expression:
and-expression
exclusive-or-expression ^ and-expression
inclusive-or-expression:
exclusive-or-expression
inclusive-or-expression | exclusive-or-expression
conditional-and-expression:
inclusive-or-expression
conditional-and-expression && inclusive-or-expression
conditional-or-expression:
conditional-and-expression
conditional-or-expression || conditional-and-expression
null-coalescing-expression:
conditional-or-expression
conditional-or-expression ?? null-coalescing-expression
conditional-expression:
null-coalescing-expression
null-coalescing-expression ? expression : expression
lambda-expression:
anonymous-function-signature => anonymous-function-body
anonymous-method-expression:
delegate explicit-anonymous-function-signatureopt block
anonymous-function-signature:
explicit-anonymous-function-signature
implicit-anonymous-function-signature
explicit-anonymous-function-signature:
( explicit-anonymous-function-parameter-listopt)
explicit-anonymous-function-parameter-list:
explicit-anonymous-function-parameter
explicit-anonymous-function-parameter-list , explicit-anonymous-function-parameter
explicit-anonymous-function-parameter:
anonymous-function-parameter-modifieropt type identifier
anonymous-function-parameter-modifier:
ref
out
implicit-anonymous-function-signature:
(implicit-anonymous-function-parameter-listopt)
implicit-anonymous-function-parameter
implicit-anonymous-function-parameter-list:
implicit-anonymous-function-parameter
implicit-anonymous-function-parameter-list , implicit-anonymous-function-parameter
implicit-anonymous-function-parameter:
identifier
anonymous-function-body:
expression
block
query-expression:
from-clause query-body
from-clause:
from typeopt identifier in expression
query-body:
query-body-clausesopt select-or-group-clause query-continuationopt
query-body-clauses:
query-body-clause
query-body-clauses query-body-clause
query-body-clause:
from-clause
let-clause
where-clause
join-clause
join-into-clause
orderby-clause
let-clause:
let identifier = expression
where-clause:
where boolean-expression
join-clause:
join typeopt identifier in expression on expression equals expression
join-into-clause:
join typeopt identifier in expression on expression equals expression into identifier
orderby-clause:
orderby orderings
orderings:
ordering
orderings , ordering
ordering:
expression ordering-directionopt
ordering-direction:
ascending
descending
select-or-group-clause:
select-clause
group-clause
select-clause:
select expression
group-clause:
group expression by expression
query-continuation:
into identifier query-body
assignment:
unary-expression assignment-operator expression
assignment-operator:
=
+=
-=
*=
/=
%=
&=
|=
^=
<<=
right-shift-assignment
expression:
non-assignment-expression
assignment
non-assignment-expression:
conditional-expression
lambda-expression
query-expression
constant-expression:
expression
boolean-expression:
expression
statement:
labeled-statement
declaration-statement
embedded-statement
embedded-statement:
block
empty-statement
expression-statement
selection-statement
iteration-statement
jump-statement
try-statement
checked-statement
unchecked-statement
lock-statement
using-statement
yield-statement
block:
{ statement-listopt}
statement-list:
statement
statement-list statement
empty-statement:
;
labeled-statement:
identifier : statement
declaration-statement:
local-variable-declaration ;
local-constant-declaration ;
local-variable-declaration:
local-variable-type local-variable-declarators
local-variable-type:
type
var
local-variable-declarators:
local-variable-declarator
local-variable-declarators , local-variable-declarator
local-variable-declarator:
identifier
identifier = local-variable-initializer
local-variable-initializer:
expression
array-initializer
local-constant-declaration:
const type constant-declarators
constant-declarators:
constant-declarator
constant-declarators , constant-declarator
constant-declarator:
identifier = constant-expression
expression-statement:
statement-expression ;
statement-expression:
invocation-expression
object-creation-expression
assignment
post-increment-expression
post-decrement-expression
pre-increment-expression
pre-decrement-expression
selection-statement:
if-statement
switch-statement
if-statement:
if( boolean-expression ) embedded-statement
if( boolean-expression ) embedded-statement else embedded-statement
switch-statement:
switch( expression ) switch-block
switch-block:
{ switch-sectionsopt}
switch-sections:
switch-section
switch-sections switch-section
switch-section:
switch-labels statement-list
switch-labels:
switch-label
switch-labels switch-label
switch-label:
case constant-expression :
default:
iteration-statement:
while-statement
do-statement
for-statement
foreach-statement
while-statement:
while( boolean-expression ) embedded-statement
do-statement:
do embedded-statement while( boolean-expression );
for-statement:
for( for-initializeropt; for-conditionopt; for-iteratoropt) embedded-statement
for-initializer:
local-variable-declaration
statement-expression-list
for-condition:
boolean-expression
for-iterator:
statement-expression-list
statement-expression-list:
statement-expression
statement-expression-list , statement-expression
foreach-statement:
foreach( local-variable-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 ;
gotocase constant-expression ;
gotodefault;
return-statement:
return expressionopt;
throw-statement:
throw expressionopt;
try-statement:
try block catch-clauses
try block finally-clause
try block catch-clauses finally-clause
catch-clauses:
specific-catch-clauses general-catch-clauseopt
specific-catch-clausesopt general-catch-clause
specific-catch-clauses:
specific-catch-clause
specific-catch-clauses specific-catch-clause
specific-catch-clause:
catch( class-type identifieropt) block
general-catch-clause:
catch block
finally-clause:
finally block
checked-statement:
checked block
unchecked-statement:
unchecked block
lock-statement:
lock( expression ) embedded-statement
using-statement:
using( resource-acquisition ) embedded-statement
resource-acquisition:
local-variable-declaration
expression
yield-statement:
yieldreturn expression ;
yieldbreak;
compilation-unit:
extern-alias-directivesopt using-directivesopt global-attributesopt
namespace-member-declarationsopt
namespace-declaration:
namespace qualified-identifier namespace-body ;opt
qualified-identifier:
identifier
qualified-identifier .identifier
namespace-body:
{ extern-alias-directivesopt using-directivesopt namespace-member-declarationsopt}
extern-alias-directives:
extern-alias-directive
extern-alias-directives extern-alias-directive
extern-alias-directive:
externalias identifier ;
using-directives:
using-directive
using-directives using-directive
using-directive:
using-alias-directive
using-namespace-directive
using-alias-directive:
using identifier = namespace-or-type-name ;
using-namespace-directive:
using namespace-name ;
namespace-member-declarations:
namespace-member-declaration
namespace-member-declarations namespace-member-declaration
namespace-member-declaration:
namespace-declaration
type-declaration
type-declaration:
class-declaration
struct-declaration
interface-declaration
enum-declaration
delegate-declaration
qualified-alias-member:
identifier :: identifier type-argument-listopt
class-declaration:
attributesopt class-modifiersoptpartialoptclass identifier type-parameter-listopt
class-baseopttype-parameter-constraints-clausesopt class-body ;opt
class-modifiers:
class-modifier
class-modifiers class-modifier
class-modifier:
new
public
protected
internal
private
abstract
sealed
static
type-parameter-list:
< type-parameters >
type-parameters:
attributesopttype-parameter
type-parameters ,attributesopttype-parameter
type-parameter:
identifier
class-base:
: class-type
: interface-type-list
: class-type , interface-type-list
interface-type-list:
interface-type
interface-type-list , interface-type
type-parameter-constraints-clauses:
type-parameter-constraints-clause
type-parameter-constraints-clauses type-parameter-constraints-clause
type-parameter-constraints-clause:
where type-parameter : type-parameter-constraints
type-parameter-constraints:
primary-constraint
secondary-constraints
constructor-constraint
primary-constraint ,secondary-constraints
primary-constraint , constructor-constraint
secondary-constraints , constructor-constraint
primary-constraint ,secondary-constraints , constructor-constraint
primary-constraint:
class-type
class
struct
secondary-constraints:
interface-type
type-parameter
secondary-constraints , interface-type
secondary-constraints ,type-parameter
constructor-constraint:
new()
class-body:
{ class-member-declarationsopt}
class-member-declarations:
class-member-declaration
class-member-declarations 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:
attributesopt constant-modifiersoptconst type constant-declarators ;
constant-modifiers:
constant-modifier
constant-modifiers constant-modifier
constant-modifier:
new
public
protected
internal
private
constant-declarators:
constant-declarator
constant-declarators , constant-declarator
constant-declarator:
identifier = constant-expression
field-declaration:
attributesopt field-modifiersopt type variable-declarators ;
field-modifiers:
field-modifier
field-modifiers field-modifier
field-modifier:
new
public
protected
internal
private
static
readonly
volatile
variable-declarators:
variable-declarator
variable-declarators , variable-declarator
variable-declarator:
identifier
identifier = variable-initializer
variable-initializer:
expression
array-initializer
method-declaration:
method-header method-body
method-header:
attributesopt method-modifiersoptpartialoptreturn-type member-name type-parameter-listopt
( formal-parameter-listopt) type-parameter-constraints-clausesopt
method-modifiers:
method-modifier
method-modifiers method-modifier
method-modifier:
new
public
protected
internal
private
static
virtual
sealed
override
abstract
extern
return-type:
type
void
member-name:
identifier
interface-type . identifier
method-body:
block
;
formal-parameter-list:
fixed-parameters
fixed-parameters , parameter-array
parameter-array
fixed-parameters:
fixed-parameter
fixed-parameters , fixed-parameter
fixed-parameter:
attributesopt parameter-modifieropt type identifier default-argumentopt
default-argument:
= expression
parameter-modifier:
ref
out
this
parameter-array:
attributesoptparams array-type identifier
property-declaration:
attributesopt property-modifiersopt type member-name { accessor-declarations }
property-modifiers:
property-modifier
property-modifiers property-modifier
property-modifier:
new
public
protected
internal
private
static
virtual
sealed
override
abstract
extern
member-name:
identifier
interface-type . identifier
accessor-declarations:
get-accessor-declaration set-accessor-declarationopt
set-accessor-declaration get-accessor-declarationopt
get-accessor-declaration:
attributesopt accessor-modifieropt get accessor-body
set-accessor-declaration:
attributesopt accessor-modifieroptset accessor-body
accessor-modifier:
protected
internal
private
protectedinternal
internalprotected
accessor-body:
block
;
event-declaration:
attributesopt event-modifiersoptevent type variable-declarators ;
attributesopt event-modifiersoptevent type member-name { event-accessor-declarations }
event-modifiers:
event-modifier
event-modifiers event-modifier
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:
attributesoptadd block
remove-accessor-declaration:
attributesoptremove block
indexer-declaration:
attributesopt indexer-modifiersopt indexer-declarator { accessor-declarations }
indexer-modifiers:
indexer-modifier
indexer-modifiers indexer-modifier
indexer-modifier:
new
public
protected
internal
private
virtual
sealed
override
abstract
extern
indexer-declarator:
type this[ formal-parameter-list ]
type interface-type .this[ formal-parameter-list ]
operator-declaration:
attributesopt operator-modifiers operator-declarator operator-body
operator-modifiers:
operator-modifier
operator-modifiers operator-modifier
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: one of
+ - ! ~ ++ -- true false
binary-operator-declarator:
type operator overloadable-binary-operator ( type identifier , type identifier )
overloadable-binary-operator:
+
-
*
/
%
&
|
^
<<
right-shift
==
!=
>
<
>=
<=
conversion-operator-declarator:
implicitoperator type ( type identifier )
explicitoperator type ( type identifier )
operator-body:
block
;
constructor-declaration:
attributesopt constructor-modifiersopt constructor-declarator constructor-body
constructor-modifiers:
constructor-modifier
constructor-modifiers constructor-modifier
constructor-modifier:
public
protected
internal
private
extern
constructor-declarator:
identifier ( formal-parameter-listopt) constructor-initializeropt
constructor-initializer:
:base( argument-listopt)
:this( argument-listopt)
constructor-body:
block
;
static-constructor-declaration:
attributesopt static-constructor-modifiers identifier () static-constructor-body
static-constructor-modifiers:
externopt static
static externopt
static-constructor-body:
block
;
destructor-declaration:
attributesoptexternopt~ identifier () destructor-body
destructor-body:
block
;
struct-declaration:
attributesopt struct-modifiersoptpartialoptstruct identifier type-parameter-listopt
struct-interfacesopttype-parameter-constraints-clausesopt struct-body ;opt
struct-modifiers:
struct-modifier
struct-modifiers struct-modifier
struct-modifier:
new
public
protected
internal
private
struct-interfaces:
: interface-type-list
struct-body:
{ struct-member-declarationsopt}
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-specifiers
non-array-type:
type
rank-specifiers:
rank-specifier
rank-specifiers rank-specifier
rank-specifier:
[ dim-separatorsopt]
dim-separators:
,
dim-separators ,
array-initializer:
{ variable-initializer-listopt}
{ variable-initializer-list ,}
variable-initializer-list:
variable-initializer
variable-initializer-list , variable-initializer
variable-initializer:
expression
array-initializer
interface-declaration:
attributesopt interface-modifiersoptpartialoptinterface
identifier variant-type-parameter-listopt interface-baseopt
type-parameter-constraints-clausesopt interface-body ;opt
interface-modifiers:
interface-modifier
interface-modifiers interface-modifier
interface-modifier:
new
public
protected
internal
private
variant-type-parameter-list:
<variant-type-parameters >
variant-type-parameters:
attributesopt variance-annotationopt type-parameter
variant-type-parameters ,attributesopt variance-annotationopttype-parameter
variance-annotation:
in
out
interface-base:
: interface-type-list
interface-body:
{ interface-member-declarationsopt}
interface-member-declarations:
interface-member-declaration
interface-member-declarations interface-member-declaration
interface-member-declaration:
interface-method-declaration
interface-property-declaration
interface-event-declaration
interface-indexer-declaration
interface-method-declaration:
attributesoptnewopt return-type identifier type-parameter-list
( formal-parameter-listopt) type-parameter-constraints-clausesopt;
interface-property-declaration:
attributesoptnewopt type identifier { interface-accessors }
interface-accessors:
attributesoptget;
attributesoptset;
attributesoptget; attributesoptset;
attributesoptset; attributesoptget;
interface-event-declaration:
attributesoptnewoptevent type identifier ;
interface-indexer-declaration:
attributesoptnewopt type this[ formal-parameter-list ]{ interface-accessors }
enum-declaration:
attributesopt enum-modifiersoptenum identifier enum-baseopt enum-body ;opt
enum-base:
: integral-type
enum-body:
{ enum-member-declarationsopt}
{ enum-member-declarations ,}
enum-modifiers:
enum-modifier
enum-modifiers enum-modifier
enum-modifier:
new
public
protected
internal
private
enum-member-declarations:
enum-member-declaration
enum-member-declarations , enum-member-declaration
enum-member-declaration:
attributesopt identifier
attributesopt identifier = constant-expression
delegate-declaration:
attributesopt delegate-modifiersoptdelegate return-type
identifier variant-type-parameter-listopt
( formal-parameter-listopt) type-parameter-constraints-clausesopt;
delegate-modifiers:
delegate-modifier
delegate-modifiers delegate-modifier
delegate-modifier:
new
public
protected
internal
private
global-attributes:
global-attribute-sections
global-attribute-sections:
global-attribute-section
global-attribute-sections global-attribute-section
global-attribute-section:
[ global-attribute-target-specifier attribute-list ]
[ global-attribute-target-specifier attribute-list ,]
global-attribute-target-specifier:
global-attribute-target :
global-attribute-target:
assembly
module
attributes:
attribute-sections
attribute-sections:
attribute-section
attribute-sections attribute-section
attribute-section:
[ attribute-target-specifieropt attribute-list ]
[ attribute-target-specifieropt attribute-list ,]
attribute-target-specifier:
attribute-target :
attribute-target:
field
event
method
param
property
return
type
attribute-list:
attribute
attribute-list , attribute
attribute:
attribute-name attribute-argumentsopt
attribute-name:
type-name
attribute-arguments:
( positional-argument-listopt)
( positional-argument-list , named-argument-list )
( named-argument-list )
positional-argument-list:
positional-argument
positional-argument-list , positional-argument
positional-argument:
argument-nameoptattribute-argument-expression
named-argument-list:
named-argument
named-argument-list , named-argument
named-argument:
identifier = attribute-argument-expression
attribute-argument-expression:
expression
A.3 Grammar extensions for unsafe code
class-modifier:
...
unsafe
struct-modifier:
...
unsafe
interface-modifier:
...
unsafe
delegate-modifier:
...
unsafe
field-modifier:
...
unsafe
method-modifier:
...
unsafe
property-modifier:
...
unsafe
event-modifier:
...
unsafe
indexer-modifier:
...
unsafe
operator-modifier:
...
unsafe
constructor-modifier:
...
unsafe
destructor-declaration:
attributesoptexternoptunsafeopt~ identifier () destructor-body
attributesoptunsafeoptexternopt~ identifier () destructor-body
static-constructor-modifiers:
externoptunsafeoptstatic
unsafeoptexternoptstatic
externoptstaticunsafeopt
unsafeoptstaticexternopt
staticexternoptunsafeopt
staticunsafeoptexternopt
embedded-statement:
...
unsafe-statement
fixed-statement
unsafe-statement:
unsafe block
type:
...
pointer-type
pointer-type:
unmanaged-type *
void*
unmanaged-type:
type
primary-no-array-creation-expression:
...
pointer-member-access
pointer-element-access
sizeof-expression
unary-expression:
...
pointer-indirection-expression
addressof-expression
pointer-indirection-expression:
* unary-expression
pointer-member-access:
primary-expression -> identifier type-argument-listopt
pointer-element-access:
primary-no-array-creation-expression [ expression ]
addressof-expression:
& unary-expression
sizeof-expression:
sizeof( unmanaged-type )
fixed-statement:
fixed( pointer-type fixed-pointer-declarators ) embedded-statement
fixed-pointer-declarators:
fixed-pointer-declarator
fixed-pointer-declarators , fixed-pointer-declarator
fixed-pointer-declarator:
identifier = fixed-pointer-initializer
fixed-pointer-initializer:
& variable-reference
expression
struct-member-declaration:
…
fixed-size-buffer-declaration
fixed-size-buffer-declaration:
attributesopt fixed-size-buffer-modifiersoptfixed buffer-element-type
fixed-size-buffer-declarators ;
fixed-size-buffer-modifiers:
fixed-size-buffer-modifier
fixed-size-buffer-modifier fixed-size-buffer-modifiers
fixed-size-buffer-modifier:
new
public
protected
internal
private
unsafe
buffer-element-type:
type
fixed-size-buffer-declarators:
fixed-size-buffer-declarator
fixed-size-buffer-declarator fixed-size-buffer-declarators
fixed-size-buffer-declarator:
identifier [ constant-expression ]
local-variable-initializer:
…
stackalloc-initializer
stackalloc-initializer:
stackalloc unmanaged-type [ expression ]
以下是開源
{
parserClass="com.apophenic.csharpplugin.parser.CSharpParser"
parserUtilClass="com.apophenic.csharpplugin.parser.CSharpParserUtil"
extends="com.intellij.extapi.psi.ASTWrapperPsiElement"
psiClassPrefix="CSharp"
psiImplClassSuffix="Impl"
psiPackage="com.apophenic.csharpplugin.psi"
psiImplPackage="com.apophenic.csharpplugin.psi.impl"
elementTypeHolderClass="com.apophenic.csharpplugin.psi.CSharpTypes"
elementTypeClass="com.apophenic.csharpplugin.CSharpElementType"
tokenTypeClass="com.apophenic.csharpplugin.CSharpTokenType"
psiImplUtilClass="com.apophenic.csharpplugin.psi.impl.CSharpPropertyImpl"
generateTokenAccessors=true
tokens=[
LBRACE = '{'
RBRACE = '}'
LBRACK = '['
RBRACK = ']'
LPAREN = '('
RPAREN = ')'
COLON = ':'
SEMI = ';'
COMMA = ','
EQ = '=='
ASSIGN = '='
NOT_EQ = '!='
NOT = '!'
PLUS_PLUS = '++'
PLUS_ASSIGN = '+='
PLUS = '+'
MINUS_MINUS = '--'
MINUS_ASSIGN = '-='
MINUS = '-'
COND_OR = '||'
BIT_OR_ASSIGN = '|='
BIT_CLEAR_ASSIGN = '&^='
BIT_CLEAR = '&^'
COND_AND = '&&'
BIT_AND_ASSIGN = '&='
BIT_AND = '&'
BIT_OR = '|'
SHIFT_LEFT_ASSIGN = '<<='
SHIFT_LEFT = '<<'
LESS_OR_EQUAL = '<='
LESS = '<'
BIT_XOR_ASSIGN = '^='
BIT_XOR = '^'
MUL_ASSIGN = '*='
MUL = '*'
QUOTIENT_ASSIGN = '/='
QUOTIENT = '/'
REMAINDER_ASSIGN = '%='
REMAINDER = '%'
SHIFT_RIGHT_ASSIGN = '>>='
SHIFT_RIGHT = '>>'
GREATER_OR_EQUAL = '>='
GREATER = '>'
DOT = '.'
APOS = ''''
QUOTE = '"'
BACK = '\'
MOD = '%'
WS = 'regexp:\s+'
COMMENT = 'regexp://.*'
DIGIT = 'regexp:\d+(\.\d*)?'
STRING = "regexp:('([^'\\]|\\.)*'|\"([^\"\\]|\\.)*\")"
ID = 'regexp:\p{Alpha}\w*'
]
}
File ::= ImportList NamespaceDec
ImportList ::= ImportDec*
ImportDec ::= using ID (ID | DOT)* SEMI
NamespaceDec ::= namespace ID LBRACE ClassList RBRACE
ClassList ::= ClassDec*
ClassDec ::= (AccessModifier? TypeModifier? Modules ID LBRACE MethodList RBRACE)
MethodList ::= (MethodDec | EnumDec | VarDec)*
MethodDec ::= AccessModifier? TypeModifier* (Type | void) ID LPAREN (Type ID ','?)* RPAREN LBRACE Expr* RBRACE
EnumDec ::= AccessModifier? enum ID LBRACE (ID ',')* ID* RBRACE
Expr ::= (VarDec | QualifiedClassDec | Arithmetic | AssignArithmetic | Switch | Using | Return | ForStatement |
ForEachStatement | IfStatement | FlowStatement | MethodCall | Property | Exception | TypeCheck)
VarDec ::= AccessModifier? TypeModifier? (BoolDec | ByteDec | CharDec | FloatDec | IntDec |
StringDec | NewTypeDec | ListDec |
GeneralDec | PreprocessorDec | CustomObjectDec | DictionaryDec)
GeneralDec ::= (PrimitiveTypes | GenericTypes)? (Property | CustomType+) ASSIGN Cast? (Arithmetic | Invocation |
TypeCheck | Property | MethodCall | Bool | null | DIGIT | CustomType) SEMI?
NewTypeDec ::= ((PrimitiveTypes | CustomType) ID | Property) ASSIGN new? (PrimitiveTypes | GenericTypes | MethodCall
| QualifiedClassDec) SEMI?
BoolDec ::= bool ID ASSIGN (true | false) SEMI {pin=2}
ByteDec ::= byte ID ASSIGN (0x DIGIT+) SEMI {pin=2} // todo
CharDec ::= char ID ASSIGN APOS ([a-zA-Z0-9] | (BACK ('u' | 'x') DIGIT{4})) APOS SEMI {pin=2}
FloatDec ::= float ID ASSIGN DIGIT '.'? 'f' SEMI {pin=2}
IntDec ::= u?(int | long | short) ID ASSIGN (Arithmetic | DIGIT) SEMI {pin=3}
StringDec ::= 'string' ID ASSIGN STRING SEMI {pin=2}
ListDec ::= GenericTypes ID ASSIGN ((new GenericTypes) | MethodCall) SEMI?
DictionaryDec ::= GenericTypes ID ASSIGN (((new GenericTypes | TypeCheck)) | MethodCall | CustomType) SEMI
QualifiedClassDec ::= 'System' ('.' (PrimitiveTypes | GenericTypes | ID))+ Argument SEMI {pin=2}
CustomObjectDec ::= CustomType ID ASSIGN (Cast (ID | DIGIT | STRING) | new CustomType LPAREN (ID | DIGIT | STRING)
RPAREN) SEMI {pin=2}
Arithmetic ::= Cast? (MethodCall | Property| DIGIT | CustomType) (Operator Cast? (MethodCall | Property| DIGIT |
CustomType))+
AssignArithmetic ::= CustomType AssignOperator (MethodCall | Property | CustomType | DIGIT | STRING)? SEMI?
Comparison ::= (Expr | CustomType | DIGIT | STRING) (CompareOperator (Expr | CustomType | DIGIT | STRING))+
Parameter ::= ID LPAREN ((PrimitiveTypes | CustomType) ID ','*)* RPAREN
Argument ::= LPAREN (out? Cast? (QualifiedClassDec | Invocation | Arithmetic| MethodCall | Property | DIGIT | STRING |
null | Bool | TypeCheck | CustomType) ','?)* RPAREN
Invocation ::= new (QualifiedClassDec | PrimitiveTypes | GenericTypes | CustomType) Argument?
MethodCall ::= (QualifiedClassDec | ID) (('.'(QualifiedClassDec | CustomType))? Argument)+ SEMI?
Property ::= (MethodCall | CustomType) ('.' ID)+ Array? SEMI?
ForStatement ::= for LPAREN IntDec Arithmetic SEMI? AssignArithmetic RPAREN LBRACE? Expr* RBRACE? {pin=10}
ForEachStatement ::= foreach LPAREN (PrimitiveTypes | CustomType) ID in (Property | MethodCall | CustomType) RPAREN LBRACE? Expr*
RBRACE? {pin=8}
Switch ::= switch LPAREN (MethodCall | Property | CustomType) RPAREN LBRACE (case LPAREN? (DIGIT | STRING |
CustomType) RPAREN? ':' Expr*)* (default ':' Expr*)? RBRACE
Using ::= using LPAREN CustomType ID ASSIGN (Invocation | MethodCall | Property) RPAREN LBRACE Expr* RBRACE {pin=9}
Return ::= return (Expr | Bool | CustomType) SEMI?
IfStatement ::= if LPAREN (Comparison | TypeCheck | CustomType) RPAREN LBRACE? Expr* RBRACE? ElseIfStatement*
ElseStatement?
private ElseStatement ::= else LBRACE? Expr* RBRACE?
private ElseIfStatement ::= else IfStatement
FlowStatement ::= (break | continue) SEMI
Exception ::= throw new MethodCall
TypeCheck ::= ID (is | as | instanceof) (QualifiedClassDec | PrimitiveTypes | GenericTypes | CustomType) // todo name +
// remove from expr?
private Cast ::= LPAREN (PrimitiveTypes | GenericTypes | CustomType) RPAREN
private Array ::= LBRACK (Arithmetic | ID | DIGIT | STRING)? RBRACK
Type ::= PrimitiveTypes | GenericTypes | CustomType
Value ::= Bool | STRING | DIGIT | null
/* Tokens */ // temp
PrimitiveTypes ::= (bool | byte | sbyte | char | decimal | double | float | int | uint | long | ulong | object | short |
ushort | var | 'string') Array? // todo
GenericTypes ::= (List | Dictionary) '<' (','? (PrimitiveTypes | GenericTypes | CustomType))+ '>' Argument?
private CustomType ::= (ID Array?) | null
Bool ::= true | false
ValueClasses ::= (struct | enum)
Modules ::= (class | interface | delegate)
PreprocessorDec ::= '#'(if | else | elif | endif | define | undef | warning | error | line | region |
endregion | pragma | pragma warning | pragma checksum) ID*
AccessModifier ::= (public | private | protected | internal)
TypeModifier ::= (abstract | async | const | event | extern | new | override | partial | readonly | sealed |
static | unsafe | virtual | volatile) // todo split into method modifiers w/ rules
ReservedWords ::= (as | base | break | case | catch | continue | do | else | false | finally | for | foreach | goto |
if | in | is | lock | namespace | new | null | out | ref | return | sizeof | stackalloc | switch |
this | throw | true | try | typeof | using | while | var | yield)
Operator ::= PLUS | MINUS | MUL | QUOTIENT | BIT_AND | BIT_OR | BIT_XOR | GREATER | GREATER_OR_EQUAL | LESS |
LESS_OR_EQUAL | MOD
AssignOperator ::= PLUS_PLUS | PLUS_ASSIGN | MINUS_MINUS | MINUS_ASSIGN | MUL_ASSIGN | QUOTIENT_ASSIGN |
REMAINDER_ASSIGN | BIT_OR_ASSIGN | BIT_CLEAR_ASSIGN | BIT_AND_ASSIGN | BIT_XOR_ASSIGN |
SHIFT_LEFT_ASSIGN | SHIFT_RIGHT_ASSIGN
CompareOperator ::= EQ | NOT_EQ | LESS | LESS_OR_EQUAL | GREATER | GREATER_OR_EQUAL | COND_OR | COND_AND
JAVA BNF
Java Syntax Specification
Programs
<compilation unit> ::= <package declaration>? <import declarations>? <type declarations>?
Declarations
<package declaration> ::= package <package name> ;
<import declarations> ::= <import declaration> | <import declarations> <import declaration>
<import declaration> ::= <single type import declaration> | <type import on demand declaration>
<single type import declaration> ::= import <type name> ;
<type import on demand declaration> ::= import <package name> . * ;
<type declarations> ::= <type declaration> | <type declarations> <type declaration>
<type declaration> ::= <class declaration> | <interface declaration> | ;
<class declaration> ::= <class modifiers>? class <identifier> <super>? <interfaces>? <class body>
<class modifiers> ::= <class modifier> | <class modifiers> <class modifier>
<class modifier> ::= public | abstract | final
<super> ::= extends <class type>
<interfaces> ::= implements <interface type list>
<interface type list> ::= <interface type> | <interface type list> , <interface type>
<class body> ::= { <class body declarations>? }
<class body declarations> ::= <class body declaration> | <class body declarations> <class body declaration>
<class body declaration> ::= <class member declaration> | <static initializer> | <constructor declaration>
<class member declaration> ::= <field declaration> | <method declaration>
<static initializer> ::= static <block>
<constructor declaration> ::= <constructor modifiers>? <constructor declarator> <throws>? <constructor body>
<constructor modifiers> ::= <constructor modifier> | <constructor modifiers> <constructor modifier>
<constructor modifier> ::= public | protected | private
<constructor declarator> ::= <simple type name> ( <formal parameter list>? )
<formal parameter list> ::= <formal parameter> | <formal parameter list> , <formal parameter>
<formal parameter> ::= <type> <variable declarator id>
<throws> ::= throws <class type list>
<class type list> ::= <class type> | <class type list> , <class type>
<constructor body> ::= { <explicit constructor invocation>? <block statements>? }
<explicit constructor invocation>::= this ( <argument list>? ) | super ( <argument list>? )
<field declaration> ::= <field modifiers>? <type> <variable declarators> ;
<field modifiers> ::= <field modifier> | <field modifiers> <field modifier>
<field modifier> ::= public | protected | private | static | final | transient | volatile
<variable declarators> ::= <variable declarator> | <variable declarators> , <variable declarator>
<variable declarator> ::= <variable declarator id> | <variable declarator id> = <variable initializer>
<variable declarator id> ::= <identifier> | <variable declarator id> [ ]
<variable initializer> ::= <expression> | <array initializer>
<method declaration> ::= <method header> <method body>
<method header> ::= <method modifiers>? <result type> <method declarator> <throws>?
<result type> ::= <type> | void
<method modifiers> ::= <method modifier> | <method modifiers> <method modifier>
<method modifier> ::= public | protected | private | static | abstract | final | synchronized | native
<method declarator> ::= <identifier> ( <formal parameter list>? )
<method body> ::= <block> | ;
<interface declaration> ::= <interface modifiers>? interface <identifier> <extends interfaces>? <interface body>
<interface modifiers> ::= <interface modifier> | <interface modifiers> <interface modifier>
<interface modifier> ::= public | abstract
<extends interfaces> ::= extends <interface type> | <extends interfaces> , <interface type>
<interface body> ::= { <interface member declarations>? }
<interface member declarations> ::= <interface member declaration> | <interface member declarations> <interface member declaration>
<interface member declaration> ::= <constant declaration> | <abstract method declaration>
<constant declaration> ::= <constant modifiers> <type> <variable declarator>
<constant modifiers> ::= public | static | final
<abstract method declaration>::= <abstract method modifiers>? <result type> <method declarator> <throws>? ;
<abstract method modifiers> ::= <abstract method modifier> | <abstract method modifiers> <abstract method modifier>
<abstract method modifier> ::= public | abstract
<array initializer> ::= { <variable initializers>? , ? }
<variable initializers> ::= <variable initializer> | <variable initializers> , <variable initializer>
<variable initializer> ::= <expression> | <array initializer>
Types
<type> ::= <primitive type> | <reference type>
<primitive type> ::= <numeric type> | boolean
<numeric type> ::= <integral type> | <floating-point type>
<integral type> ::= byte | short | int | long | char
<floating-point type> ::= float | double
<reference type> ::= <class or interface type> | <array type>
<class or interface type> ::= <class type> | <interface type>
<class type> ::= <type name>
<interface type> ::= <type name>
<array type> ::= <type> [ ]
Blocks and Commands
<block> ::= { <block statements>? }
<block statements> ::= <block statement> | <block statements> <block statement>
<block statement> ::= <local variable declaration statement> | <statement>
<local variable declaration statement> ::= <local variable declaration> ;
<local variable declaration> ::= <type> <variable declarators>
<statement> ::= <statement without trailing substatement> | <labeled statement> | <if then statement> | <if then else statement> | <while statement> | <for statement>
<statement no short if> ::= <statement without trailing substatement> | <labeled statement no short if> | <if then else statement no short if> | <while statement no short if> | <for statement no short if>
<statement without trailing substatement> ::= <block> | <empty statement> | <expression statement> | <switch statement> | <do statement> | <break statement> | <continue statement> | <return statement> | <synchronized statement> | <throws statements> | <try statement>
<empty statement> ::= ;
<labeled statement> ::= <identifier> : <statement>
<labeled statement no short if> ::= <identifier> : <statement no short if>
<expression statement> ::= <statement expression> ;
<statement expression> ::= <assignment> | <preincrement expression> | <postincrement expression> | <predecrement expression> | <postdecrement expression> | <method invocation> | <class instance creation expression>
<if then statement>::= if ( <expression> ) <statement>
<if then else statement>::= if ( <expression> ) <statement no short if> else <statement>
<if then else statement no short if> ::= if ( <expression> ) <statement no short if> else <statement no short if>
<switch statement> ::= switch ( <expression> ) <switch block>
<switch block> ::= { <switch block statement groups>? <switch labels>? }
<switch block statement groups> ::= <switch block statement group> | <switch block statement groups> <switch block statement group>
<switch block statement group> ::= <switch labels> <block statements>
<switch labels> ::= <switch label> | <switch labels> <switch label>
<switch label> ::= case <constant expression> : | default :
<while statement> ::= while ( <expression> ) <statement>
<while statement no short if> ::= while ( <expression> ) <statement no short if>
<do statement> ::= do <statement> while ( <expression> ) ;
<for statement> ::= for ( <for init>? ; <expression>? ; <for update>? ) <statement>
<for statement no short if> ::= for ( <for init>? ; <expression>? ; <for update>? ) <statement no short if>
<for init> ::= <statement expression list> | <local variable declaration>
<for update> ::= <statement expression list>
<statement expression list> ::= <statement expression> | <statement expression list> , <statement expression>
<break statement> ::= break <identifier>? ;
<continue statement> ::= continue <identifier>? ;
<return statement> ::= return <expression>? ;
<throws statement> ::= throw <expression> ;
<synchronized statement> ::= synchronized ( <expression> ) <block>
<try statement> ::= try <block> <catches> | try <block> <catches>? <finally>
<catches> ::= <catch clause> | <catches> <catch clause>
<catch clause> ::= catch ( <formal parameter> ) <block>
<finally > ::= finally <block>
Expressions
<constant expression> ::= <expression>
<expression> ::= <assignment expression>
<assignment expression> ::= <conditional expression> | <assignment>
<assignment> ::= <left hand side> <assignment operator> <assignment expression>
<left hand side> ::= <expression name> | <field access> | <array access>
<assignment operator> ::= = | *= | /= | %= | += | -= | <<= | >>= | >>>= | &= | ^= | |=
<conditional expression> ::= <conditional or expression> | <conditional or expression> ? <expression> : <conditional expression>
<conditional or expression> ::= <conditional and expression> | <conditional or expression> || <conditional and expression>
<conditional and expression> ::= <inclusive or expression> | <conditional and expression> && <inclusive or expression>
<inclusive or expression> ::= <exclusive or expression> | <inclusive or expression> | <exclusive or expression>
<exclusive or expression> ::= <and expression> | <exclusive or expression> ^ <and expression>
<and expression> ::= <equality expression> | <and expression> & <equality expression>
<equality expression> ::= <relational expression> | <equality expression> == <relational expression> | <equality expression> != <relational expression>
<relational expression> ::= <shift expression> | <relational expression> < <shift expression> | <relational expression> > <shift expression> | <relational expression> <= <shift expression> | <relational expression> >= <shift expression> | <relational expression> instanceof <reference type>
<shift expression> ::= <additive expression> | <shift expression> << <additive expression> | <shift expression> >> <additive expression> | <shift expression> >>> <additive expression>
<additive expression> ::= <multiplicative expression> | <additive expression> + <multiplicative expression> | <additive expression> - <multiplicative expression>
<multiplicative expression> ::= <unary expression> | <multiplicative expression> * <unary expression> | <multiplicative expression> / <unary expression> | <multiplicative expression> % <unary expression>
<cast expression> ::= ( <primitive type> ) <unary expression> | ( <reference type> ) <unary expression not plus minus>
<unary expression> ::= <preincrement expression> | <predecrement expression> | + <unary expression> | - <unary expression> | <unary expression not plus minus>
<predecrement expression> ::= -- <unary expression>
<preincrement expression> ::= ++ <unary expression>
<unary expression not plus minus> ::= <postfix expression> | ~ <unary expression> | ! <unary expression> | <cast expression>
<postdecrement expression> ::= <postfix expression> --
<postincrement expression> ::= <postfix expression> ++
<postfix expression> ::= <primary> | <expression name> | <postincrement expression> | <postdecrement expression>
<method invocation> ::= <method name> ( <argument list>? ) | <primary> . <identifier> ( <argument list>? ) | super . <identifier> ( <argument list>? )
<field access> ::= <primary> . <identifier> | super . <identifier>
<primary> ::= <primary no new array> | <array creation expression>
<primary no new array> ::= <literal> | this | ( <expression> ) | <class instance creation expression> | <field access> | <method invocation> | <array access>
<class instance creation expression> ::= new <class type> ( <argument list>? )
<argument list> ::= <expression> | <argument list> , <expression>
<array creation expression> ::= new <primitive type> <dim exprs> <dims>? | new <class or interface type> <dim exprs> <dims>?
<dim exprs> ::= <dim expr> | <dim exprs> <dim expr>
<dim expr> ::= [ <expression> ]
<dims> ::= [ ] | <dims> [ ]
<array access> ::= <expression name> [ <expression> ] | <primary no new array> [ <expression>]
Tokens
<package name> ::= <identifier> | <package name> . <identifier>
<type name> ::= <identifier> | <package name> . <identifier>
<simple type name> ::= <identifier>
<expression name> ::= <identifier> | <ambiguous name> . <identifier>
<method name> ::= <identifier> | <ambiguous name>. <identifier>
<ambiguous name>::= <identifier> | <ambiguous name>. <identifier>
<literal> ::= <integer literal> | <floating-point literal> | <boolean literal> | <character literal> | <string literal> | <null literal>
<integer literal> ::= <decimal integer literal> | <hex integer literal> | <octal integer literal>
<decimal integer literal> ::= <decimal numeral> <integer type suffix>?
<hex integer literal> ::= <hex numeral> <integer type suffix>?
<octal integer literal> ::= <octal numeral> <integer type suffix>?
<integer type suffix> ::= l | L
<decimal numeral> ::= 0 | <non zero digit> <digits>?
<digits> ::= <digit> | <digits> <digit>
<digit> ::= 0 | <non zero digit>
<non zero digit> ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<hex numeral> ::= 0 x <hex digit> | 0 X <hex digit> | <hex numeral> <hex digit>
<hex digit> :: = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | A | B | C | D | E | F
<octal numeral> ::= 0 <octal digit> | <octal numeral> <octal digit>
<octal digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
<floating-point literal> ::= <digits> . <digits>? <exponent part>? <float type suffix>?
<digits> <exponent part>? <float type suffix>?
<exponent part> ::= <exponent indicator> <signed integer>
<exponent indicator> ::= e | E
<signed integer> ::= <sign>? <digits>
<sign> ::= + | -
<float type suffix> ::= f | F | d | D
<boolean literal> ::= true | false
<character literal> ::= ' <single character> ' | ' <escape sequence> '
<single character> ::= <input character> except ' and \
<string literal> ::= " <string characters>?"
<string characters> ::= <string character> | <string characters> <string character>
<string character> ::= <input character> except " and \ | <escape character>
<null literal> ::= null
<keyword> ::= abstract | boolean | break | byte | case | catch | char | class | const | continue | default | do | double | else | extends | final | finally | float | for | goto | if | implements | import | instanceof | int | interface | long | native | new | package | private | protected | public | return | short | static | super | switch | synchronized | this | throw | throws | transient | try | void | volatile | while
The character set for Java is Unicode, a 16-bit character set. This is the set denoted by <input character>. Unicode effectively contains the familiar 7-bit ASCII characters as a subset, and includes "escape code" designations of the form \udddd (where each d is from <hex digit>). In the extended BNF for Java the optional appearance of X is written X?, and the iterative appearance of X is written {X}.
The syntax category <identifier> consists of strings that must start with a letter - including underscore (_) and dollar sign ($) - followed by any number of letters and digits. Characters of numerous international languages are recognized as "letters" in Java. A Java letter is a character for which the method Character.isJavaLetter returns true. A Java letter-or-digit is a character for which the method Character.isJaveLetterOrDigit returns true. Also, <identifier> includes none of the keywords given above - these are reserved words in Java.
The only BNF extention used here is the optional construct which is written with '?' added as a suffix to a terminal or non-terminal. Note that '*', '{', and '}' are all terminal symbols. This BNF definition does not address such pragmatic issues as comment conventions and the use of "white space" to delimit tokens. This BNF also does not express numerous "context-sensitive" restrictions on syntax. For instance, type use of identifiers must be consistent with the required declarations, there are size limitations on numerical literals, etc.
C語言BNF
The syntax of C in Backus-Naur Form
<translation-unit> ::= {<external-declaration>}*
<external-declaration> ::= <function-definition>
| <declaration>
<function-definition> ::= {<declaration-specifier>}* <declarator> {<declaration>}* <compound-statement>
<declaration-specifier> ::= <storage-class-specifier>
| <type-specifier>
| <type-qualifier>
<storage-class-specifier> ::= auto
| register
| static
| extern
| typedef
<type-specifier> ::= void
| char
| short
| int
| long
| float
| double
| signed
| unsigned
| <struct-or-union-specifier>
| <enum-specifier>
| <typedef-name>
<struct-or-union-specifier> ::= <struct-or-union> <identifier> { {<struct-declaration>}+ }
| <struct-or-union> { {<struct-declaration>}+ }
| <struct-or-union> <identifier>
<struct-or-union> ::= struct
| union
<struct-declaration> ::= {<specifier-qualifier>}* <struct-declarator-list>
<specifier-qualifier> ::= <type-specifier>
| <type-qualifier>
<struct-declarator-list> ::= <struct-declarator>
| <struct-declarator-list> , <struct-declarator>
<struct-declarator> ::= <declarator>
| <declarator> : <constant-expression>
| : <constant-expression>
<declarator> ::= {<pointer>}? <direct-declarator>
<pointer> ::= * {<type-qualifier>}* {<pointer>}?
<type-qualifier> ::= const
| volatile
<direct-declarator> ::= <identifier>
| ( <declarator> )
| <direct-declarator> [ {<constant-expression>}? ]
| <direct-declarator> ( <parameter-type-list> )
| <direct-declarator> ( {<identifier>}* )
<constant-expression> ::= <conditional-expression>
<conditional-expression> ::= <logical-or-expression>
| <logical-or-expression> ? <expression> : <conditional-expression>
<logical-or-expression> ::= <logical-and-expression>
| <logical-or-expression || <logical-and-expression>
<logical-and-expression> ::= <inclusive-or-expression>
| <logical-and-expression && <inclusive-or-expression>
<inclusive-or-expression> ::= <exclusive-or-expression>
| <inclusive-or-expression> | <exclusive-or-expression>
<exclusive-or-expression> ::= <and-expression>
| <exclusive-or-expression> ^ <and-expression>
<and-expression> ::= <equality-expression>
| <and-expression> & <equality-expression>
<equality-expression> ::= <relational-expression>
| <equality-expression> == <relational-expression>
| <equality-expression> != <relational-expression>
<relational-expression> ::= <shift-expression>
| <relational-expression> < <shift-expression>
| <relational-expression> > <shift-expression>
| <relational-expression> <= <shift-expression>
| <relational-expression> >= <shift-expression>
<shift-expression> ::= <additive-expression>
| <shift-expression> << <additive-expression>
| <shift-expression> >> <additive-expression>
<additive-expression> ::= <multiplicative-expression>
| <additive-expression> + <multiplicative-expression>
| <additive-expression> - <multiplicative-expression>
<multiplicative-expression> ::= <cast-expression>
| <multiplicative-expression> * <cast-expression>
| <multiplicative-expression> / <cast-expression>
| <multiplicative-expression> % <cast-expression>
<cast-expression> ::= <unary-expression>
| ( <type-name> ) <cast-expression>
<unary-expression> ::= <postfix-expression>
| ++ <unary-expression>
| -- <unary-expression>
| <unary-operator> <cast-expression>
| sizeof <unary-expression>
| sizeof <type-name>
<postfix-expression> ::= <primary-expression>
| <postfix-expression> [ <expression> ]
| <postfix-expression> ( {<assignment-expression>}* )
| <postfix-expression> . <identifier>
| <postfix-expression> -> <identifier>
| <postfix-expression> ++
| <postfix-expression> --
<primary-expression> ::= <identifier>
| <constant>
| <string>
| ( <expression> )
<constant> ::= <integer-constant>
| <character-constant>
| <floating-constant>
| <enumeration-constant>
<expression> ::= <assignment-expression>
| <expression> , <assignment-expression>
<assignment-expression> ::= <conditional-expression>
| <unary-expression> <assignment-operator> <assignment-expression>
<assignment-operator> ::= =
| *=
| /=
| %=
| +=
| -=
| <<=
| >>=
| &=
| ^=
| |=
<unary-operator> ::= &
| *
| +
| -
| ~
| !
<type-name> ::= {<specifier-qualifier>}+ {<abstract-declarator>}?
<parameter-type-list> ::= <parameter-list>
| <parameter-list> , ...
<parameter-list> ::= <parameter-declaration>
| <parameter-list> , <parameter-declaration>
<parameter-declaration> ::= {<declaration-specifier>}+ <declarator>
| {<declaration-specifier>}+ <abstract-declarator>
| {<declaration-specifier>}+
<abstract-declarator> ::= <pointer>
| <pointer> <direct-abstract-declarator>
| <direct-abstract-declarator>
<direct-abstract-declarator> ::= ( <abstract-declarator> )
| {<direct-abstract-declarator>}? [ {<constant-expression>}? ]
| {<direct-abstract-declarator>}? ( {<parameter-type-list>|? )
<enum-specifier> ::= enum <identifier> { <enumerator-list> }
| enum { <enumerator-list> }
| enum <identifier>
<enumerator-list> ::= <enumerator>
| <enumerator-list> , <enumerator>
<enumerator> ::= <identifier>
| <identifier> = <constant-expression>
<typedef-name> ::= <identifier>
<declaration> ::= {<declaration-specifier>}+ {<init-declarator>}*
<init-declarator> ::= <declarator>
| <declarator> = <initializer>
<initializer> ::= <assignment-expression>
| { <initializer-list> }
| { <initializer-list> , }
<initializer-list> ::= <initializer>
| <initializer-list> , <initializer>
<compound-statement> ::= { {<declaration>}* {<statement>}* }
<statement> ::= <labeled-statement>
| <expression-statement>
| <compound-statement>
| <selection-statement>
| <iteration-statement>
| <jump-statement>
<labeled-statement> ::= <identifier> : <statement>
| case <constant-expression> : <statement>
| default : <statement>
<expression-statement> ::= {<expression>}? ;
<selection-statement> ::= if ( <expression> ) <statement>
| if ( <expression> ) <statement> else <statement>
| switch ( <expression> ) <statement>
<iteration-statement> ::= while ( <expression> ) <statement>
| do <statement> while ( <expression> ) ;
| for ( {<expression>}? ; {<expression>}? ; {<expression>}? ) <statement>
<jump-statement> ::= goto <identifier> ;
| continue ;
| break ;
| return {<expression>}? ;
This grammar was adapted from Section A13 of The C programming language, 2nd edition, by Brian W. Kernighan and Dennis M. Ritchie,Prentice Hall, 1988.
以上收集於網絡
相關信息推薦先留言