Visual Basic プログラムのコンパイルでは、最初に Unicode 文字の生ストリームを順序付けされた構文トークンのセットに変換します。 Visual Basic 言語は自由形式ではないため、トークンのセットはさらに一連の論理行に分割されます。 論理行は、ストリームの先頭または行ターミネータから、行連結の前にない次の行ターミネータまで、またはストリームの末尾まで及ぶ。
"注: バージョン 9.0 の言語で XML リテラル式が導入されたため、Visual Basic には構文コンテキストに関係なく Visual Basic コードをトークン化できるという意味で、明確な字句文法がなくなりました。 これは、XML と Visual Basic には異なる字句規則があり、特定の時点で使用される構文規則のセットは、その時点で処理されている構文コンストラクトによって異なるためです。 この仕様では、通常の Visual Basic コードの字句規則のガイドとして、この字句文法セクションが保持されます。
LogicalLineStart
: LogicalLine*
;
LogicalLine
: LogicalLineElement* Comment? LineTerminator
;
LogicalLineElement
: WhiteSpace
| LineContinuation
| Token
;
Token
: Identifier
| Keyword
| Literal
| Separator
| Operator
;
文字と行
Visual Basic プログラムは、Unicode 文字セットの文字で構成されます。
Character:
'<Any Unicode character except a LineTerminator>'
;
ライン ターミネータ
Unicode 改行文字は、論理行を区切ります。
LineTerminator
: '<Unicode 0x00D>'
| '<Unicode 0x00A>'
| '<CR>'
| '<LF>'
| '<Unicode 0x2028>'
| '<Unicode 0x2029>'
;
行継続
行の継続は、テキスト行の最後の文字 (空白以外) として 1 つのアンダースコア文字の直前にある少なくとも 1 つの空白文字で構成されます。 行連結を使用すると、論理行を複数の物理行にまたがることができます。 行の継続は空白であるかのように扱われますが、空白ではない場合でも扱われます。
LineContinuation
: WhiteSpace '_' WhiteSpace* LineTerminator
;
次のプログラムは、いくつかの行の継続を示しています。
Module Test
Sub Print( _
Param1 As Integer, _
Param2 As Integer )
If (Param1 < Param2) Or _
(Param1 > Param2) Then
Console.WriteLine("Not equal")
End If
End Function
End Module
構文文法の一部の場所では、 暗黙的な行の継続が可能です。 行ターミネータが検出されたとき
コンマ (
,)、かっこ (()、中かっこ ({)、または埋め込み式 (<%=) を開くメンバー修飾子 (
.または.@または...) の後(何かが修飾されている (つまり、暗黙的なWithコンテキストを使用していない) 場合)閉じかっこ (
))、中かっこ (})、または埋め込み式を閉じる (%>) の前属性コンテキストで小さい (
<) の後属性コンテキスト内のより大きい (
>) の前ファイル レベル以外の属性コンテキストのより大きい (
>) の後前後のクエリ演算子 (
Where、Order、Selectなど)式コンテキスト内の二項演算子 (
+、-、/、*など) の後任意のコンテキストでの代入演算子 (
=、:=、+=、-=など) の後。
行ターミネータは、行連結であるかのように扱われます。
Comma
: ',' LineTerminator?
;
Period
: '.' LineTerminator?
;
OpenParenthesis
: '(' LineTerminator?
;
CloseParenthesis
: LineTerminator? ')'
;
OpenCurlyBrace
: '{' LineTerminator?
;
CloseCurlyBrace
: LineTerminator? '}'
;
Equals
: '=' LineTerminator?
;
ColonEquals
: ':' '=' LineTerminator?
;
たとえば、前の例は次のように記述することもできます。
Module Test
Sub Print(
Param1 As Integer,
Param2 As Integer)
If (Param1 < Param2) Or
(Param1 > Param2) Then
Console.WriteLine("Not equal")
End If
End Function
End Module
暗黙的な行の継続は、指定されたトークンの直前または後にのみ推論されます。 これらは、行の継続の前または後には推論されません。 例えば次が挙げられます。
Dim y = 10
' Error: Expression expected for assignment to x
Dim x = _
y
条件付きコンパイル コンテキストでは、行の継続は推論されません。 (注。 コンパイルされていない条件付きコンパイル ブロック内のテキストは構文的に有効である必要がないため、この最後の制限が必要です。したがって、特に将来言語が拡張されるにつれて、ブロック内のテキストが条件付きコンパイル ステートメントによって誤って "取得" される可能性があります)。
空白
空白は 個別のトークンにのみ使用され、それ以外の場合は無視されます。 空白のみを含む論理行は無視されます。 (注。 行終端記号は空白とは見なされません。
WhiteSpace
: '<Unicode class Zs>'
| '<Unicode Tab 0x0009>'
;
コメント
コメントは、一重引用符またはキーワード REMで始まります。 単一引用符文字は、ASCII 単一引用符文字、Unicode 左一重引用符文字、または Unicode 右一重引用符文字のいずれかです。 コメントはソース行の任意の場所で開始でき、物理行の末尾はコメントを終了します。 コンパイラは、コメントの先頭と行終端記号の間の文字を無視します。 したがって、コメントは行連結を使用して複数行にわたって拡張することはできません。
Comment
: CommentMarker Character*
;
CommentMarker
: SingleQuoteCharacter
| 'REM'
;
SingleQuoteCharacter
: '\''
| '<Unicode 0x2018>'
| '<Unicode 0x2019>'
;
識別子
識別子は名前です。 Visual Basic 識別子は、1 つの例外を除き、Unicode 標準付属書 15 に準拠しています。識別子はアンダースコア (コネクタ) 文字で始まる場合があります。 識別子がアンダースコアで始まる場合は、行の継続からあいまいさを解消するために、少なくとも 1 つの有効な識別子文字を含める必要があります。
Identifier
: NonEscapedIdentifier TypeCharacter?
| Keyword TypeCharacter
| EscapedIdentifier
;
NonEscapedIdentifier
: '<Any IdentifierName but not Keyword>'
;
EscapedIdentifier
: '[' IdentifierName ']'
;
IdentifierName
: IdentifierStart IdentifierCharacter*
;
IdentifierStart
: AlphaCharacter
| UnderscoreCharacter IdentifierCharacter
;
IdentifierCharacter
: UnderscoreCharacter
| AlphaCharacter
| NumericCharacter
| CombiningCharacter
| FormattingCharacter
;
AlphaCharacter
: '<Unicode classes Lu,Ll,Lt,Lm,Lo,Nl>'
;
NumericCharacter
: '<Unicode decimal digit class Nd>'
;
CombiningCharacter
: '<Unicode combining character classes Mn, Mc>'
;
FormattingCharacter
: '<Unicode formatting character class Cf>'
;
UnderscoreCharacter
: '<Unicode connection character class Pc>'
;
IdentifierOrKeyword
: Identifier
| Keyword
;
通常の識別子はキーワードと一致しない場合がありますが、エスケープされた識別子または型文字を持つ識別子は可能です。 エスケープされた識別子は、角かっこで区切られた識別子です。 エスケープされた識別子は、キーワードと一致する可能性があり、型文字がない場合を除き、通常の識別子と同じ規則に従います。
この例では、classという名前のクラスを、booleanという名前のパラメーターを受け取り、メソッドを呼び出す shared という名前の共有メソッドを使用して定義します。
Class [class]
Shared Sub [shared]([boolean] As Boolean)
If [boolean] Then
Console.WriteLine("true")
Else
Console.WriteLine("false")
End If
End Sub
End Class
Module [module]
Sub Main()
[class].[shared](True)
End Sub
End Module
識別子では大文字と小文字が区別されないため、大文字と小文字のみが異なる場合、2 つの識別子は同じ識別子と見なされます。 (注。 Unicode 標準の 1 対 1 のケース マッピングは、識別子を比較するときに使用され、ロケール固有の大文字と小文字のマッピングは無視されます)。
型文字
型文字は、前の識別子の型を表します。 型文字は識別子の一部とは見なされません。
TypeCharacter
: IntegerTypeCharacter
| LongTypeCharacter
| DecimalTypeCharacter
| SingleTypeCharacter
| DoubleTypeCharacter
| StringTypeCharacter
;
IntegerTypeCharacter
: '%'
;
LongTypeCharacter
: '&'
;
DecimalTypeCharacter
: '@'
;
SingleTypeCharacter
: '!'
;
DoubleTypeCharacter
: '#'
;
StringTypeCharacter
: '$'
;
宣言に型文字が含まれている場合、型文字は宣言自体で指定された型と一致する必要があります。それ以外の場合は、コンパイル時エラーが発生します。 宣言で型が省略されている場合 (たとえば、 As 句を指定しない場合)、型文字は宣言の型として暗黙的に置き換えられます。
識別子とその型文字の間に空白を使用できません。 適切な文字がないため、 Byte、 SByte、 UShort、 Short、 UInteger 、または ULongの型文字はありません。
型を概念的に持たない識別子 (名前空間名など) または型文字の型と一致しない識別子に型文字を追加すると、コンパイル時エラーが発生します。
次の例は、型文字の使用を示しています。
' The follow line will cause an error: standard modules have no type.
Module Test1#
End Module
Module Test2
' This function takes a Long parameter and returns a String.
Function Func$(Param&)
' The following line causes an error because the type character
' conflicts with the declared type of Func and Param.
Func# = CStr(Param@)
' The following line is valid.
Func$ = CStr(Param&)
End Function
End Module
!型文字は、言語の型文字と区切り文字の両方として使用できるという点で特別な問題を発生させます。 あいまいさを取り除くために、 ! 文字は、その後に続く文字が識別子を開始できない限り、型文字です。 可能な場合、 ! 文字は区切り文字であり、型文字ではありません。
キーワード
キーワードは、言語コンストラクトで特別な意味を持つ単語です。 すべてのキーワードは言語によって予約されており、識別子がエスケープされない限り、識別子として使用することはできません。 (Note.EndIf、 GoSub、 Let、 Variant、 Wend はキーワードとして保持されますが、Visual Basic では使用されなくなりました)。
Keyword
: 'AddHandler' | 'AddressOf' | 'Alias' | 'And'
| 'AndAlso' | 'As' | 'Boolean' | 'ByRef'
| 'Byte' | 'ByVal' | 'Call' | 'Case'
| 'Catch' | 'CBool' | 'CByte' | 'CChar'
| 'CDate' | 'CDbl' | 'CDec' | 'Char'
| 'CInt' | 'Class' | 'CLng' | 'CObj'
| 'Const' | 'Continue' | 'CSByte' | 'CShort'
| 'CSng' | 'CStr' | 'CType' | 'CUInt'
| 'CULng' | 'CUShort' | 'Date' | 'Decimal'
| 'Declare' | 'Default' | 'Delegate' | 'Dim'
| 'DirectCast' | 'Do' | 'Double' | 'Each'
| 'Else' | 'ElseIf' | 'End' | 'EndIf'
| 'Enum' | 'Erase' | 'Error' | 'Event'
| 'Exit' | 'False' | 'Finally' | 'For'
| 'Friend' | 'Function' | 'Get' | 'GetType'
| 'GetXmlNamespace' | 'Global' | 'GoSub' | 'GoTo'
| 'Handles' | 'If' | 'Implements' | 'Imports'
| 'In' | 'Inherits' | 'Integer' | 'Interface'
| 'Is' | 'IsNot' | 'Let' | 'Lib'
| 'Like' | 'Long' | 'Loop' | 'Me'
| 'Mod' | 'Module' | 'MustInherit' | 'MustOverride'
| 'MyBase' | 'MyClass' | 'Namespace' | 'Narrowing'
| 'New' | 'Next' | 'Not' | 'Nothing'
| 'NotInheritable' | 'NotOverridable' | 'Object' | 'Of'
| 'On' | 'Operator' | 'Option' | 'Optional'
| 'Or' | 'OrElse' | 'Overloads' | 'Overridable'
| 'Overrides' | 'ParamArray' | 'Partial' | 'Private'
| 'Property' | 'Protected' | 'Public' | 'RaiseEvent'
| 'ReadOnly' | 'ReDim' | 'REM' | 'RemoveHandler'
| 'Resume' | 'Return' | 'SByte' | 'Select'
| 'Set' | 'Shadows' | 'Shared' | 'Short'
| 'Single' | 'Static' | 'Step' | 'Stop'
| 'String' | 'Structure' | 'Sub' | 'SyncLock'
| 'Then' | 'Throw' | 'To' | 'True'
| 'Try' | 'TryCast' | 'TypeOf' | 'UInteger'
| 'ULong' | 'UShort' | 'Using' | 'Variant'
| 'Wend' | 'When' | 'While' | 'Widening'
| 'With' | 'WithEvents' | 'WriteOnly' | 'Xor'
;
リテラル
リテラルは、型の特定の値のテキスト表現です。 リテラル型には、ブール値、整数、浮動小数点、文字列、文字、および日付が含まれます。
Literal
: BooleanLiteral
| IntegerLiteral
| FloatingPointLiteral
| StringLiteral
| CharacterLiteral
| DateLiteral
| Nothing
;
ブール型リテラル
True
Falseは、それぞれ true と false の状態にマップされるBoolean型のリテラルです。
BooleanLiteral
: 'True' | 'False'
;
整数リテラル
整数リテラルには、10 進数 (底 10)、16 進数 (底 16)、または 8 進数 (底 8) を指定できます。 10 進整数リテラルは、10 進数 (0 から 9) の文字列です。 16 進数リテラル &H 後に 16 進数の文字列 (0 から 9、A から F) が続きます。 8 進数リテラル &O 後に 8 進数の文字列 (0 から 7) が続きます。 10 進リテラルは整数リテラルの 10 進値を直接表し、8 進数リテラルと 16 進リテラルは整数リテラルの 2 進値を表します (したがって、 &H8000S はオーバーフロー エラーではなく -32768 になります)。
IntegerLiteral
: IntegralLiteralValue IntegralTypeCharacter?
;
IntegralLiteralValue
: IntLiteral
| HexLiteral
| OctalLiteral
;
IntegralTypeCharacter
: ShortCharacter
| UnsignedShortCharacter
| IntegerCharacter
| UnsignedIntegerCharacter
| LongCharacter
| UnsignedLongCharacter
| IntegerTypeCharacter
| LongTypeCharacter
;
ShortCharacter
: 'S'
;
UnsignedShortCharacter
: 'US'
;
IntegerCharacter
: 'I'
;
UnsignedIntegerCharacter
: 'UI'
;
LongCharacter
: 'L'
;
UnsignedLongCharacter
: 'UL'
;
IntLiteral
: Digit+
;
HexLiteral
: '&' 'H' HexDigit+
;
OctalLiteral
: '&' 'O' OctalDigit+
;
Digit
: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
;
HexDigit
: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
| 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
;
OctalDigit
: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7'
;
リテラルの型は、その値または次の型文字によって決まります。 型文字が指定されていない場合、 Integer 型の範囲内の値は Integerとして型指定され、 Integer の範囲外の値は Longとして型指定されます。 整数リテラルの型が整数リテラルを保持するのに十分なサイズでない場合、コンパイル時エラーが発生します。 (注。最も自然な文字はB(16 進数リテラルの有効な文字)であるため、Byteの型文字はありません)。
Floating-Point リテラル
浮動小数点リテラルは、整数リテラルの後に、省略可能な小数点 (ASCII ピリオド文字) と仮数、および省略可能な底 10 指数が続きます。 既定では、浮動小数点リテラルは Double型です。
Single、Double、またはDecimal型の文字が指定されている場合、リテラルはその型になります。 浮動小数点リテラルの型が浮動小数点リテラルを保持するのに十分なサイズでない場合、コンパイル時エラーが発生します。
"注:
Decimalデータ型では、値の末尾のゼロをエンコードできることに注意してください。 現在、この仕様では、 Decimal リテラル内の末尾のゼロをコンパイラで受け入れる必要があるかどうかについてのコメントは付けません。
FloatingPointLiteral
: FloatingPointLiteralValue FloatingPointTypeCharacter?
| IntLiteral FloatingPointTypeCharacter
;
FloatingPointTypeCharacter
: SingleCharacter
| DoubleCharacter
| DecimalCharacter
| SingleTypeCharacter
| DoubleTypeCharacter
| DecimalTypeCharacter
;
SingleCharacter
: 'F'
;
DoubleCharacter
: 'R'
;
DecimalCharacter
: 'D'
;
FloatingPointLiteralValue
: IntLiteral '.' IntLiteral Exponent?
| '.' IntLiteral Exponent?
| IntLiteral Exponent
;
Exponent
: 'E' Sign? IntLiteral
;
Sign
: '+'
| '-'
;
文字列リテラル
文字列リテラルは、ASCII 二重引用符文字、Unicode 左二重引用符文字、または Unicode 右二重引用符文字で始まり、終わる 0 個以上の Unicode 文字のシーケンスです。 文字列内では、2 つの二重引用符文字のシーケンスは、文字列内の二重引用符を表すエスケープ シーケンスです。
StringLiteral
: DoubleQuoteCharacter StringCharacter* DoubleQuoteCharacter
;
DoubleQuoteCharacter
: '"'
| '<unicode left double-quote 0x201c>'
| '<unicode right double-quote 0x201D>'
;
StringCharacter
: '<Any character except DoubleQuoteCharacter>'
| DoubleQuoteCharacter DoubleQuoteCharacter
;
文字列定数は、 String 型です。
Module Test
Sub Main()
' This prints out: ".
Console.WriteLine("""")
' This prints out: a"b.
Console.WriteLine("a""b")
' This causes a compile error due to mismatched double-quotes.
Console.WriteLine("a"b")
End Sub
End Module
コンパイラは、定数文字列式を文字列リテラルに置き換えることができます。 各文字列リテラルでは、必ずしも新しい文字列インスタンスが生成されるとは限りません。 バイナリ比較セマンティクスを使用する文字列等価演算子に従って等価な 2 つ以上の文字列リテラルが同じプログラムに出現する場合、これらの文字列リテラルは同じ文字列インスタンスを参照できます。 たとえば、次のプログラムの出力は、2 つのリテラルが同じ文字列インスタンスを参照する可能性があるため、 True を返す場合があります。
Module Test
Sub Main()
Dim a As Object = "he" & "llo"
Dim b As Object = "hello"
Console.WriteLine(a Is b)
End Sub
End Module
文字リテラル
文字リテラルは、 Char 型の 1 つの Unicode 文字を表します。 2 つの二重引用符文字は、二重引用符文字を表すエスケープ シーケンスです。
CharacterLiteral
: DoubleQuoteCharacter StringCharacter DoubleQuoteCharacter 'C'
;
Module Test
Sub Main()
' This prints out: a.
Console.WriteLine("a"c)
' This prints out: ".
Console.WriteLine(""""c)
End Sub
End Module
日付リテラル
日付リテラルは、 Date 型の値として表される特定の時点を表します。
DateLiteral
: '#' WhiteSpace* DateOrTime WhiteSpace* '#'
;
DateOrTime
: DateValue WhiteSpace+ TimeValue
| DateValue
| TimeValue
;
DateValue
: MonthValue '/' DayValue '/' YearValue
| MonthValue '-' DayValue '-' YearValue
;
TimeValue
: HourValue ':' MinuteValue ( ':' SecondValue )? WhiteSpace* AMPM?
| HourValue WhiteSpace* AMPM
;
MonthValue
: IntLiteral
;
DayValue
: IntLiteral
;
YearValue
: IntLiteral
;
HourValue
: IntLiteral
;
MinuteValue
: IntLiteral
;
SecondValue
: IntLiteral
;
AMPM
: 'AM' | 'PM'
;
リテラルでは、日付と時刻の両方、日付のみ、または時刻のみを指定できます。 日付値を省略すると、グレゴリオ暦の年 1 の 1 月 1 日が想定されます。 時刻値を省略すると、午前 12:00:00 が想定されます。
日付値の年値の解釈に関する問題を回避するために、年の値を 2 桁にすることはできません。 最初の世紀の AD/CE で日付を表す場合は、先頭にゼロを指定する必要があります。
時間値は、24 時間の値または 12 時間の値を使用して指定できます。 AM または PM を省略する時間値は、24 時間の値と見なされます。 時間値で分が省略されている場合、リテラル 0 が既定で使用されます。 時間値で秒が省略されている場合、リテラル 0 が既定で使用されます。 分と秒の両方を省略する場合は、 AM または PM を指定する必要があります。 指定された日付値が Date 型の範囲外の場合は、コンパイル時エラーが発生します。
次の例には、いくつかの日付リテラルが含まれています。
Dim d As Date
d = # 8/23/1970 3:45:39AM #
d = # 8/23/1970 # ' Date value: 8/23/1970 12:00:00AM.
d = # 3:45:39AM # ' Date value: 1/1/1 3:45:39AM.
d = # 3:45:39 # ' Date value: 1/1/1 3:45:39AM.
d = # 13:45:39 # ' Date value: 1/1/1 1:45:39PM.
d = # 1AM # ' Date value: 1/1/1 1:00:00AM.
d = # 13:45:39PM # ' This date value is not valid.
何もない
Nothing は特別なリテラルです。型が含まれていないため、型パラメーターを含め、型システム内のすべての型に変換できます。 特定の型に変換された場合、その型の既定値に相当します。
Nothing
: 'Nothing'
;
区切り
次の ASCII 文字は区切り記号です。
Separator
: '(' | ')' | '{' | '}' | '!' | '#' | ',' | '.' | ':' | '?'
;
演算子文字
次の ASCII 文字または文字シーケンスは、演算子を表します。
Operator
: '&' | '*' | '+' | '-' | '/' | '\\' | '^' | '<' | '=' | '>'
;
Visual Basic language spec