Visual Basic 프로그램의 컴파일에는 먼저 유니코드 문자의 원시 스트림을 순서가 지정된 어휘 토큰 집합으로 변환하는 작업이 포함됩니다. 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 프로그램은 유니코드 문자 집합의 문자로 구성됩니다.
Character:
'<Any Unicode character except a LineTerminator>'
;
줄 종결자
유니코드 줄 바꿈 문자는 논리 줄을 구분합니다.
LineTerminator
: '<Unicode 0x00D>'
| '<Unicode 0x00A>'
| '<CR>'
| '<LF>'
| '<Unicode 0x2028>'
| '<Unicode 0x2029>'
;
줄 연속
줄 연속은 텍스트 줄에서 공백이 아닌 마지막 문자로 단일 밑줄 문자 바로 앞에 오는 하나 이상의 공백 문자로 구성됩니다. 줄 연속을 사용하면 논리 줄이 둘 이상의 실제 줄에 걸쳐 있습니다. 줄 연속은 공백인 것처럼 처리됩니다.
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 작은따옴표 문자, 유니코드 왼쪽 작은따옴표 문자 또는 유니코드 오른쪽 작은따옴표 문자입니다. 주석은 원본 줄의 아무 곳이나 시작할 수 있으며 실제 줄의 끝은 주석을 종료합니다. 컴파일러는 주석의 시작 부분과 줄 종결자 사이의 문자를 무시합니다. 따라서 주석은 줄 연속을 사용하여 여러 줄로 확장할 수 없습니다.
Comment
: CommentMarker Character*
;
CommentMarker
: SingleQuoteCharacter
| 'REM'
;
SingleQuoteCharacter
: '\''
| '<Unicode 0x2018>'
| '<Unicode 0x2019>'
;
식별자
식별자는 이름입니다. Visual Basic 식별자는 한 가지 예외를 제외하고 유니코드 표준 부록 15를 준수합니다. 식별자는 밑줄(커넥터) 문자로 시작할 수 있습니다. 식별자가 밑줄로 시작하는 경우 줄 연속에서 식별자를 구분하려면 하나 이상의 유효한 식별자 문자를 포함해야 합니다.
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
;
일반 식별자는 키워드와 일치하지 않을 수 있지만 형식 문자가 있는 이스케이프된 식별자 또는 식별자는 일치할 수 있습니다. 이 스케이프된 식별자는 대괄호로 구분된 식별자입니다. 이스케이프된 식별자는 키워드와 일치할 수 있고 형식 문자가 없을 수 있다는 점을 제외하고 일반 식별자와 동일한 규칙을 따릅니다.
이 예제에서는 명명된 매개 변수를 사용하고 메서드를 호출하는 명명된 공유 메서드를 사용하여 명명 classsharedboolean 된 클래스를 정의합니다.
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
식별자는 대/소문자를 구분하지 않으므로 두 식별자는 대/소문자만 다른 경우 동일한 식별자로 간주됩니다. (참고. 유니코드 표준 일대일 사례 매핑은 식별자를 비교할 때 사용되며 로캘별 사례 매핑은 무시됩니다.)
문자 입력
형식 문자는 이전 식별자의 형식을 표시합니다. 형식 문자는 식별자의 일부로 간주되지 않습니다.
TypeCharacter
: IntegerTypeCharacter
| LongTypeCharacter
| DecimalTypeCharacter
| SingleTypeCharacter
| DoubleTypeCharacter
| StringTypeCharacter
;
IntegerTypeCharacter
: '%'
;
LongTypeCharacter
: '&'
;
DecimalTypeCharacter
: '@'
;
SingleTypeCharacter
: '!'
;
DoubleTypeCharacter
: '#'
;
StringTypeCharacter
: '$'
;
선언에 형식 문자가 포함된 경우 형식 문자는 선언 자체에 지정된 형식에 동의해야 합니다. 그렇지 않으면 컴파일 시간 오류가 발생합니다. 선언에서 형식을 생략하는 경우(예: 절을 As 지정하지 않은 경우) 형식 문자는 선언의 형식으로 암시적으로 대체됩니다.
식별자와 해당 형식 문자 사이에 공백이 있을 수 없습니다. 적절한 문자Byte가 부족하여 , SByte, UIntegerUShortShort또는 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
형식 문자는 형식 문자 ! 와 언어의 구분 기호로 모두 사용할 수 있다는 특수한 문제를 제공합니다. 모호성을 ! 제거하기 위해 문자 뒤에 있는 문자가 식별자를 시작할 수 없는 한 문자는 형식 문자입니다. 가능한 경우 문자는 ! 형식 문자가 아닌 구분 기호입니다.
키워드
키워드는 언어 구문에 특별한 의미가 있는 단어입니다. 모든 키워드는 언어에 의해 예약되며 식별자를 이스케이프하지 않는 한 식별자로 사용할 수 없습니다. (참고.EndIfGoSub , , Let및 VariantWend 키워드는 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진수(base 10), 16진수(base 16) 또는 8진수(base 8)일 수 있습니다. 10진수 정수 리터럴은 10진수 문자열(0-9)입니다. 16진수 리터럴 뒤에 &H 16진수 문자열(0-9, A-F)이 잇습니다. 8진수 리터럴 &O 뒤에 8진수 문자열(0-7)이 잇습니다. 10진수 리터럴은 정수 리터럴의 10진수 값을 직접 나타내는 반면, 8진수 및 16진수 리터럴은 정수 리터럴의 이진 값을 나타냅니다(따라서 &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입력됩니다. 정수 리터럴의 형식이 정수 리터럴을 저장할 크기가 부족한 경우 컴파일 시간 오류가 발생합니다. (참고. 가장 자연스러운 문자 Byte 는 16진수 리터럴의 법적 문자 B이기 때문에 형식 문자가 없습니다.)
Floating-Point 리터럴
부동 소수점 리터럴은 정수 리터럴 뒤에 선택적 소수점(ASCII 마침표 문자) 및 가수, 선택적 base 10 지수입니다. 기본적으로 부동 소수점 리터럴은 형식 Double입니다.
Single, Double또는 Decimal 형식 문자를 지정하면 리터럴이 해당 형식입니다. 부동 소수점 리터럴의 형식이 부동 소수점 리터럴을 저장할 크기가 부족한 경우 컴파일 시간 오류가 발생합니다.
메모. 데이터 형식은 Decimal 후행 0을 값으로 인코딩할 수 있습니다. 이 사양은 현재 컴파일러에서 Decimal 리터럴의 후행 0을 적용해야 하는지 여부에 대해 아무런 언급도 하지 않습니다.
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 큰따옴표 문자, 유니코드 왼쪽 큰따옴표 문자 또는 유니코드 오른쪽 큰따옴표 문자로 시작하고 끝나는 0개 이상의 유니코드 문자 시퀀스입니다. 문자열 내에서 두 개의 큰따옴표 문자 시퀀스는 문자열의 큰따옴표를 나타내는 이스케이프 시퀀스입니다.
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
컴파일러는 상수 문자열 식을 문자열 리터럴로 바꿀 수 있습니다. 각 문자열 리터럴이 반드시 새 문자열 인스턴스를 발생시키지는 않습니다. 이진 비교 의미 체계를 사용하는 문자열 같음 연산자에 해당하는 두 개 이상의 문자열 리터럴이 동일한 프로그램에 나타나면 이러한 문자열 리터럴은 동일한 문자열 인스턴스를 참조할 수 있습니다. 예를 들어 다음 프로그램의 출력은 두 리터럴이 동일한 문자열 인스턴스를 참조할 수 있기 때문에 반환 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 단일 유니코드 문자를 나타냅니다. 두 개의 큰따옴표 문자는 큰따옴표 문자를 나타내는 이스케이프 시퀀스입니다.
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이 됩니다.
날짜 값의 연도 값을 해석하는 데 문제가 발생하지 않도록 연도 값은 두 자리가 될 수 없습니다. 1세기 AD/CE에서 날짜를 표현할 때 선행 0을 지정해야 합니다.
시간 값은 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