Lexikalische Grammatik

Die Kompilierung eines Visual Basic-Programms umfasst zuerst das Übersetzen des unformatierten Unicode-Zeichenstroms in einen sortierten Satz lexikalischer Token. Da die Visual Basic-Sprache kein freies Format aufweist, wird der Tokensatz dann weiter in eine Reihe logischer Zeilen unterteilt. Eine logische Linie erstreckt sich entweder vom Anfang des Datenstroms oder von einem Zeilenterminator bis zum nächsten Zeilenterminator, dem keine Zeilenfortsetzung oder bis zum Ende des Datenstroms vorausgeht.

Hinweis: Mit der Einführung von XML-Literalausdrücken in Version 9.0 der Sprache verfügt Visual Basic nicht mehr über eine unterschiedliche lexikalische Grammatik in dem Sinne, dass Visual Basic-Code ohne Berücksichtigung des syntaktischen Kontexts tokenisiert werden kann. Dies ist darauf zurückzuführen, dass XML und Visual Basic unterschiedliche lexikalische Regeln haben und der Satz lexikalischer Regeln, die zu einem bestimmten Zeitpunkt verwendet werden, von dem abhängig ist, was syntaktisches Konstrukt zu diesem Zeitpunkt verarbeitet wird. Diese Spezifikation behält diesen lexikalischen Grammatikabschnitt als Leitfaden für die lexikalischen Regeln regulärer Visual Basic-Code bei.

LogicalLineStart
    : LogicalLine*
    ;

LogicalLine
    : LogicalLineElement* Comment? LineTerminator
    ;

LogicalLineElement
    : WhiteSpace
    | LineContinuation
    | Token
    ;

Token
    : Identifier
    | Keyword
    | Literal
    | Separator
    | Operator
    ;

Zeichen und Zeilen

Visual Basic-Programme bestehen aus Zeichen aus dem Unicode-Zeichensatz.

Character:
    '<Any Unicode character except a LineTerminator>'
    ;

Zeilenabbruchzeichen

Unicode-Zeilenumbruchzeichen trennen logische Zeilen.

LineTerminator
    : '<Unicode 0x00D>'
    | '<Unicode 0x00A>'
    | '<CR>'
    | '<LF>'
    | '<Unicode 0x2028>'
    | '<Unicode 0x2029>'
    ;

Zeilenfortsetzung

Eine Zeilenfortsetzung besteht aus mindestens einem Leerzeichen, das unmittelbar vor einem einzelnen Unterstrichzeichen als letztes Zeichen (außer Leerzeichen) in einer Textzeile steht. Eine Zeilenfortsetzung ermöglicht es einer logischen Linie, mehr als eine physische Linie zu umfassen. Zeilenfortsetzungen werden so behandelt, als wären sie Leerzeichen, auch wenn sie nicht vorhanden sind.

LineContinuation
    : WhiteSpace '_' WhiteSpace* LineTerminator
    ;

Das folgende Programm zeigt einige Zeilenfortsetzungen:

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

Einige Stellen in der syntaktischen Grammatik ermöglichen implizite Zeilenfortsetzungen. Wenn ein Zeilenendpunkt gefunden wird

  • nach einem Komma (,), öffnen Sie Klammern ((), öffnen Sie geschweifte geschweifte Klammern ({) oder öffnen Sie einen eingebetteten Ausdruck (<%=)

  • nach einem Memberqualifizierer (. oder ....@ ), vorausgesetzt, dass etwas qualifiziert wird (d. h. kein impliziter With Kontext verwendet)

  • vor einer schließenden Klammer ()), schließen Sie geschweifte geschweifte Klammer (}) oder schließen Sie eingebetteten Ausdruck (%>)

  • nach einem kleiner als (<) in einem Attributkontext

  • vor einem größer als (>) in einem Attributkontext

  • nach einem Größer-als-(>) in einem Attributkontext auf Nicht-Dateiebene

  • Vor- und Nachabfrageoperatoren (Where, Order, Selectusw.)

  • nach binären Operatoren (+, -, /, *usw.) in einem Ausdruckskontext

  • nach Zuordnungsoperatoren (=, :=, +=, -=usw.) in einem beliebigen Kontext.

Der Zeilenendpunkt wird so behandelt, als ob es sich um eine Zeilenfortsetzung handelte.

Comma
    : ',' LineTerminator?
    ;

Period
    : '.' LineTerminator?
    ;

OpenParenthesis
    : '(' LineTerminator?
    ;

CloseParenthesis
    : LineTerminator? ')'
    ;

OpenCurlyBrace
    : '{' LineTerminator?
    ;

CloseCurlyBrace
    : LineTerminator? '}'
    ;

Equals
    : '=' LineTerminator?
    ;

ColonEquals
    : ':' '=' LineTerminator?
    ;

Das vorherige Beispiel könnte z. B. auch wie folgt geschrieben werden:

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

Implizite Zeilenfortsetzungen werden nur direkt vor oder nach dem angegebenen Token abgeleitet. Sie werden nicht vor oder nach einer Zeilenfortsetzung abgeleitet. Beispiel:

Dim y = 10
' Error: Expression expected for assignment to x
Dim x = _

y

Zeilenfortsetzungen werden in bedingten Kompilierungskontexten nicht abgeleitet. (Hinweis. Diese letzte Einschränkung ist erforderlich, da Text in bedingten Kompilierungsblöcken, die nicht kompiliert werden, nicht syntaktisch gültig sein müssen. Daher kann der Text im Block versehentlich von der Anweisung für die bedingte Kompilierung "aufgenommen" werden, insbesondere, wenn die Sprache in Zukunft erweitert wird.)

Leerraum

Leerzeichen dienen nur zum Trennen von Token und werden andernfalls ignoriert. Logische Zeilen, die nur Leerzeichen enthalten, werden ignoriert. (Hinweis. Zeilenterminatoren werden nicht als Leerzeichen betrachtet.)

WhiteSpace
    : '<Unicode class Zs>'
    | '<Unicode Tab 0x0009>'
    ;

Kommentare

Ein Kommentar beginnt mit einem einfachen Anführungszeichen oder dem Schlüsselwort REM. Ein einfaches Anführungszeichen ist entweder ein einfaches ASCII-Anführungszeichen, ein einfaches Unicode-Anführungszeichen oder ein Unicode-Zeichen mit einfachem Anführungszeichen. Kommentare können an einer beliebigen Stelle in einer Quellzeile beginnen, und das Ende der physischen Zeile endet den Kommentar. Der Compiler ignoriert die Zeichen zwischen dem Anfang des Kommentars und dem Zeilenterminator. Daher können Kommentare nicht über mehrere Zeilen hinweg mithilfe von Zeilenfortsetzungen erweitert werden.

Comment
    : CommentMarker Character*
    ;

CommentMarker
    : SingleQuoteCharacter
    | 'REM'
    ;

SingleQuoteCharacter
    : '\''
    | '<Unicode 0x2018>'
    | '<Unicode 0x2019>'
    ;

Bezeichner

Ein Bezeichner ist ein Name. Visual Basic-Bezeichner entsprechen dem Unicode-Standard-Anhang 15 mit einer Ausnahme: Bezeichner können mit einem Unterstrich (Verbinderzeichen) beginnen. Wenn ein Bezeichner mit einem Unterstrich beginnt, muss er mindestens ein anderes gültiges Bezeichnerzeichen enthalten, um ihn von einer Zeilenfortsetzung zu unterscheiden.

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
    ;

Reguläre Bezeichner stimmen möglicherweise nicht mit Schlüsselwörtern überein, aber Escape-IDs oder Bezeichner mit einem Typzeichen können. Ein Escapebezeichner ist ein Bezeichner , der durch eckige Klammern getrennt ist. Escape-IDs entsprechen den gleichen Regeln wie reguläre Bezeichner, mit der Ausnahme, dass sie Schlüsselwörtern entsprechen und keine Typzeichen aufweisen.

This example defines a class named class with a shared method named shared that takes a parameter named boolean and then calls the method.

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

Bei Bezeichnern wird die Groß-/Kleinschreibung nicht beachtet. Daher werden zwei Bezeichner als derselbe Bezeichner betrachtet, wenn sie nur im Fall unterschiedlich sind. (Hinweis. Die 1:1-Fallzuordnungen von Unicode Standard werden beim Vergleichen von Bezeichnern und gebietsschemaspezifischen Fallzuordnungen ignoriert.)

Geben Sie Zeichen ein

Ein Typzeichen gibt den Typ des vorherigen Bezeichners an. Das Typzeichen wird nicht als Teil des Bezeichners betrachtet.

TypeCharacter
    : IntegerTypeCharacter
    | LongTypeCharacter
    | DecimalTypeCharacter
    | SingleTypeCharacter
    | DoubleTypeCharacter
    | StringTypeCharacter
    ;

IntegerTypeCharacter
    : '%'
    ;

LongTypeCharacter
    : '&'
    ;

DecimalTypeCharacter
    : '@'
    ;

SingleTypeCharacter
    : '!'
    ;

DoubleTypeCharacter
    : '#'
    ;

StringTypeCharacter
    : '$'
    ;

Wenn eine Deklaration ein Typzeichen enthält, muss das Typzeichen dem in der Deklaration selbst angegebenen Typ zustimmen; andernfalls tritt ein Kompilierungszeitfehler auf. Wenn die Deklaration den Typ ausgelassen (z. B. wenn keine Klausel angegeben As wird), wird das Typzeichen implizit als Typ der Deklaration ersetzt.

Es kann kein Leerzeichen zwischen einem Bezeichner und seinem Typzeichen bestehen. Es gibt keine Typzeichen für Byte, SByte, , UShortoder Short, ULongUInteger aufgrund eines Mangels an geeigneten Zeichen.

Das Anfügen eines Typzeichens an einen Bezeichner, der konzeptionell keinen Typ aufweist (z. B. einen Namespacenamen) oder einem Bezeichner, dessen Typ nicht mit dem Typ des Typzeichens übereinstimmt, verursacht einen Kompilierungszeitfehler.

Das folgende Beispiel zeigt die Verwendung von Typzeichen:

' 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

Das Typzeichen ! stellt ein besonderes Problem dar, da es sowohl als Typzeichen als auch als Trennzeichen in der Sprache verwendet werden kann. Um Mehrdeutigkeit zu entfernen, ist ein ! Zeichen ein Typzeichen, solange das darauf folgende Zeichen keinen Bezeichner starten kann. Wenn dies möglich ist, ist das ! Zeichen ein Trennzeichen, kein Typzeichen.

Schlüsselwörter

Ein Schlüsselwort ist ein Wort, das in einem Sprachkonstrukt eine besondere Bedeutung hat. Alle Schlüsselwörter sind für die Sprache reserviert und dürfen nicht als Bezeichner verwendet werden, es sei denn, die Bezeichner werden escaped. (Hinweis.EndIf, GoSub, , VariantLetund Wend werden als Schlüsselwörter beibehalten, obwohl sie in Visual Basic nicht mehr verwendet werden.)

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'         
    ;

Literale

Ein Literal ist eine Textdarstellung eines bestimmten Werts eines Typs. Literaltypen umfassen boolesche, ganze Zahl, Gleitkomma, Zeichenfolge, Zeichen und Datum.

Literal
    : BooleanLiteral
    | IntegerLiteral
    | FloatingPointLiteral
    | StringLiteral
    | CharacterLiteral
    | DateLiteral
    | Nothing
    ;

Boolesche Literale

True und False sind Literale des Typs, die Boolean dem wahr- bzw. falsch-Zustand zugeordnet sind.

BooleanLiteral
    : 'True' | 'False'
    ;

Ganzzahlige Literale

Ganzzahlige Literale können dezimal (Basis 10), hexadezimal (Basis 16) oder Oktal (Basis 8) sein. Ein ganzzahliges Dezimalliteral ist eine Zeichenfolge von Dezimalziffern (0-9). Auf ein hexadezimales Literal folgt &H eine Zeichenfolge mit hexadezimalen Ziffern (0-9, A-F). Auf ein oktales Literal folgt &O eine Zeichenfolge von oktalen Ziffern (0-7). Dezimalliterale stellen den Dezimalwert des integralen Literals direkt dar, während oktale und hexadezimale Literale den Binären Wert des ganzzahligen Literals darstellen (also &H8000S -32768, kein Überlauffehler).

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'
    ;

Der Typ eines Literals wird durch seinen Wert oder durch das folgende Typzeichen bestimmt. Wenn kein Typzeichen angegeben wird, werden Werte im Bereich des Integer Typs als Integer; Werte außerhalb des Bereichs Integer eingegeben als Long. Wenn der Typ eines ganzzahligen Literals nicht ausreicht, um das ganze Literal zu enthalten, führt ein Kompilierungszeitfehler zu einem Fehler. (Hinweis. Es gibt kein Typzeichen, Byte da das natürlichste Zeichen sein Bwürde , das ein rechtliches Zeichen in einem hexadezimalen Literal ist.)

Floating-Point Literale

Ein Gleitkommaliteral ist ein ganzzahliges Literal, gefolgt von einem optionalen Dezimalkomma (dem ASCII-Punktzeichen) und mantissa und einer optionalen Basis 10-Exponent. Standardmäßig ist ein Gleitkommaliteral vom Typ Double. Wenn das SingleZeichen , Doubleoder Decimal Typzeichen angegeben ist, ist das Literal dieses Typs. Wenn der Typ eines Gleitkommaliterals nicht ausreicht, um das Gleitkommaliteral zu halten, führt ein Kompilierungszeitfehler zu einem Fehler.If a floating-point literal is of insufficient size to hold the floating-point literal, a compile-time error results.

Hinweis: Beachten Sie, dass der Decimal Datentyp nachfolgende Nullen in einem Wert codieren kann. Die Spezifikation gibt derzeit keinen Kommentar darüber ab, ob nachfolgende Nullen in einem Decimal Literal von einem Compiler berücksichtigt werden sollen.

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
    : '+'
    | '-'
    ;

Zeichenfolgenliterale

Ein Zeichenfolgenliteral ist eine Abfolge von null oder mehr Unicode-Zeichen, die mit einem ASCII-Anführungszeichen, einem Unicode-Zeichen mit doppeltem Anführungszeichen oder einem Unicode-Zeichen mit doppeltem Anführungszeichen enden. Innerhalb einer Zeichenfolge ist eine Sequenz von zwei doppelten Anführungszeichen eine Escapesequenz, die ein doppeltes Anführungszeichen in der Zeichenfolge darstellt.

StringLiteral
    : DoubleQuoteCharacter StringCharacter* DoubleQuoteCharacter
    ;

DoubleQuoteCharacter
    : '"'
    | '<unicode left double-quote 0x201c>'
    | '<unicode right double-quote 0x201D>'
    ;

StringCharacter
    : '<Any character except DoubleQuoteCharacter>'
    | DoubleQuoteCharacter DoubleQuoteCharacter
    ;

Eine Zeichenfolgenkonstante ist vom String Typ.

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

Der Compiler darf einen Konstantenzeichenfolgenausdruck durch ein Zeichenfolgenliteral ersetzen. Jedes Zeichenfolgenliteral führt nicht unbedingt zu einer neuen Zeichenfolgeninstanz. Wenn zwei oder mehr Zeichenfolgenliterale, die entsprechend dem Zeichenfolgengleichstellungsoperator mit binärer Vergleichsemantik entsprechen, im selben Programm angezeigt werden, können diese Zeichenfolgenliterale auf dieselbe Zeichenfolgeninstanz verweisen. Die Ausgabe des folgenden Programms kann beispielsweise zurückgegeben werden True , da die beiden Literale auf dieselbe Zeichenfolgeninstanz verweisen können.

Module Test
    Sub Main()
        Dim a As Object = "he" & "llo"
        Dim b As Object = "hello"
        Console.WriteLine(a Is b)
    End Sub
End Module

Zeichenliterale

Ein Zeichenliteral stellt ein einzelnes Unicode-Zeichen des Char Typs dar. Zwei doppelte Anführungszeichen sind eine Escapesequenz, die das doppelte Anführungszeichen darstellt.

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

Datumsliterale

Ein Datumsliteral stellt einen bestimmten Zeitpunkt dar, der als Wert des Date Typs ausgedrückt wird.

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'
    ;    

Das Literal kann sowohl ein Datum als auch eine Uhrzeit, nur ein Datum oder nur eine Uhrzeit angeben. Wenn der Datumswert nicht angegeben wird, wird der 1. Januar des Jahres 1 im gregorianischen Kalender angenommen. Wenn der Zeitwert weggelassen wird, wird 12:00:00 Uhr angenommen.

Um Probleme beim Interpretieren des Jahreswerts in einem Datumswert zu vermeiden, darf der Jahreswert nicht zwei Ziffern sein. Beim Ausdruck eines Datums im ersten Jahrhundert AD/CE müssen führende Nullen angegeben werden.

Ein Zeitwert kann entweder mit einem 24-Stunden-Wert oder einem 12-Stunden-Wert angegeben werden; Zeitwerte, die ein AM - oder auslassen, PM werden als 24-Stunden-Werte angenommen. Wenn ein Zeitwert die Minuten ausgelassen, wird das Literal 0 standardmäßig verwendet. Wenn ein Zeitwert die Sekunden ausgelassen, wird das Literal 0 standardmäßig verwendet. Wenn sowohl Minuten als auch Sekunde weggelassen werden, müssen AM sie PM angegeben werden. Wenn der angegebene Datumswert außerhalb des Bereichs des Date Typs liegt, tritt ein Kompilierungszeitfehler auf.

Das folgende Beispiel enthält mehrere Datumsliterale.

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.

Nichts

Nothing ist ein spezielles Literal; es verfügt nicht über einen Typ und ist in alle Typen im Typsystem, einschließlich Typparametern, konvertierbar. Wenn sie in einen bestimmten Typ konvertiert wird, entspricht sie dem Standardwert dieses Typs.

Nothing
    : 'Nothing'
    ;

Trennzeichen

Die folgenden ASCII-Zeichen sind Trennzeichen:

Separator
    : '(' | ')' | '{' | '}' | '!' | '#' | ',' | '.' | ':' | '?'
    ;

Operatorzeichen

Die folgenden ASCII-Zeichen oder -Sequenzen geben Operatoren an:

Operator
    : '&' | '*' | '+' | '-' | '/' | '\\' | '^' | '<' | '=' | '>'
    ;