Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
La compilazione di un programma Visual Basic comporta innanzitutto la conversione del flusso non elaborato di caratteri Unicode in un set ordinato di token lessicali. Poiché il linguaggio Visual Basic non è in formato libero, il set di token viene quindi suddiviso ulteriormente in una serie di righe logiche. Una linea logica si estende dall'inizio del flusso o da un terminatore di riga fino al terminatore di riga successivo che non è preceduto da una continuazione di riga o fino alla fine del flusso.
Nota. Con l'introduzione di espressioni letterali XML nella versione 9.0 del linguaggio, Visual Basic non ha più una grammatica lessicale distinta nel senso che il codice visual Basic può essere tokenizzato senza considerare il contesto sintattico. Ciò è dovuto al fatto che XML e Visual Basic hanno regole lessicali diverse e il set di regole lessicali in uso in qualsiasi momento dipende da quale costrutto sintattico viene elaborato in quel momento. Questa specifica mantiene questa sezione grammaticale lessicale come guida alle regole lessicali del normale codice Visual Basic.
LogicalLineStart
: LogicalLine*
;
LogicalLine
: LogicalLineElement* Comment? LineTerminator
;
LogicalLineElement
: WhiteSpace
| LineContinuation
| Token
;
Token
: Identifier
| Keyword
| Literal
| Separator
| Operator
;
Caratteri e righe
I programmi Visual Basic sono costituiti da caratteri del set di caratteri Unicode.
Character:
'<Any Unicode character except a LineTerminator>'
;
Caratteri di terminazione riga
Caratteri di interruzione di riga Unicode separano le righe logiche.
LineTerminator
: '<Unicode 0x00D>'
| '<Unicode 0x00A>'
| '<CR>'
| '<LF>'
| '<Unicode 0x2028>'
| '<Unicode 0x2029>'
;
Continuazione di riga
Una continuazione di riga è costituita da almeno un carattere di spazio vuoto che precede immediatamente un singolo carattere di sottolineatura come ultimo carattere (diverso da spazi vuoti) in una riga di testo. Una continuazione di riga consente a una linea logica di estendersi su più linee fisiche. Le continuazioni di riga vengono considerate come se fossero spazi vuoti, anche se non lo sono.
LineContinuation
: WhiteSpace '_' WhiteSpace* LineTerminator
;
Il programma seguente illustra alcune continuazioni di riga:
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
Alcune posizioni nella grammatica sintattica consentono le continuazioni di riga implicite. Quando viene rilevato un terminatore di riga
dopo una virgola (
,), parentesi aperta ((), parentesi graffa aperta ({) o espressione incorporata aperta (<%=)dopo un qualificatore membro (
.o.@o...), a condizione che un elemento sia qualificato (ad esempio, non usa un contesto implicitoWith)prima di una parentesi chiusa (
)), chiudere parentesi graffe (}) o chiudere un'espressione incorporata (%>)dopo un valore minore di (
<) in un contesto di attributoprima di un valore maggiore di (
>) in un contesto di attributodopo un valore maggiore di (
>) in un contesto di attributo non a livello di fileoperatori di query prima e dopo (
Where,Order,Selecte così via)dopo operatori binari (
+,-,/,*e così via) in un contesto di espressionedopo gli operatori di assegnazione (
=,:=,+=,-=e così via) in qualsiasi contesto.
il terminatore di riga viene considerato come se fosse una continuazione di riga.
Comma
: ',' LineTerminator?
;
Period
: '.' LineTerminator?
;
OpenParenthesis
: '(' LineTerminator?
;
CloseParenthesis
: LineTerminator? ')'
;
OpenCurlyBrace
: '{' LineTerminator?
;
CloseCurlyBrace
: LineTerminator? '}'
;
Equals
: '=' LineTerminator?
;
ColonEquals
: ':' '=' LineTerminator?
;
Ad esempio, l'esempio precedente può anche essere scritto come:
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
Le continuazioni di riga implicite verranno dedotte solo prima o dopo il token specificato. Non verranno dedotti prima o dopo una continuazione di riga. Per esempio:
Dim y = 10
' Error: Expression expected for assignment to x
Dim x = _
y
Le continuazioni di riga non verranno dedotte nei contesti di compilazione condizionale. (Nota. Questa ultima restrizione è obbligatoria perché il testo nei blocchi di compilazione condizionale non compilati non deve essere sintatticamente valido. Di conseguenza, il testo nel blocco potrebbe essere accidentalmente "prelevato" dall'istruzione di compilazione condizionale, in particolare quando il linguaggio viene esteso in futuro.
Spazi vuoti
Lo spazio vuoto serve solo per separare i token e viene altrimenti ignorato. Le righe logiche contenenti solo spazi vuoti vengono ignorate. (Nota. I terminatori di riga non sono considerati spazi vuoti.
WhiteSpace
: '<Unicode class Zs>'
| '<Unicode Tab 0x0009>'
;
Commenti
Un commento inizia con un carattere virgolette singole o la parola chiave REM. Un carattere virgolette singole è un carattere virgolette singole ASCII, un carattere a virgoletta singola Unicode o un carattere a virgoletta singola Unicode. I commenti possono iniziare ovunque in una riga di origine e la fine della riga fisica termina il commento. Il compilatore ignora i caratteri tra l'inizio del commento e il terminatore di riga. Di conseguenza, i commenti non possono estendersi tra più righe utilizzando continuazioni di riga.
Comment
: CommentMarker Character*
;
CommentMarker
: SingleQuoteCharacter
| 'REM'
;
SingleQuoteCharacter
: '\''
| '<Unicode 0x2018>'
| '<Unicode 0x2019>'
;
Identificatori
Un identificatore è un nome. Gli identificatori di Visual Basic sono conformi all'allegato Standard Unicode 15 con un'eccezione: gli identificatori possono iniziare con un carattere di sottolineatura (connettore). Se un identificatore inizia con un carattere di sottolineatura, deve contenere almeno un altro carattere di identificatore valido per disambiguarlo da una continuazione di riga.
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
;
Gli identificatori regolari possono non corrispondere alle parole chiave, ma gli identificatori o gli identificatori preceduti da escape con un carattere di tipo possono. Un identificatore di escape è un identificatore delimitato da parentesi quadre. Gli identificatori preceduti da escape seguono le stesse regole degli identificatori regolari, ad eccezione del fatto che possono corrispondere a parole chiave e potrebbero non avere caratteri di tipo.
Questo esempio definisce una classe denominata class con un metodo condiviso denominato shared che accetta un parametro denominato boolean e quindi chiama il metodo .
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
Gli identificatori non fanno distinzione tra maiuscole e minuscole, quindi due identificatori vengono considerati lo stesso identificatore se differiscono solo nel caso. (Nota. I mapping di maiuscole e minuscole Standard Unicode vengono usati per confrontare gli identificatori e tutti i mapping di maiuscole e minuscole specifiche delle impostazioni locali vengono ignorati.
Digitare caratteri
Un carattere di tipo indica il tipo dell'identificatore precedente. Il carattere di tipo non è considerato parte dell'identificatore.
TypeCharacter
: IntegerTypeCharacter
| LongTypeCharacter
| DecimalTypeCharacter
| SingleTypeCharacter
| DoubleTypeCharacter
| StringTypeCharacter
;
IntegerTypeCharacter
: '%'
;
LongTypeCharacter
: '&'
;
DecimalTypeCharacter
: '@'
;
SingleTypeCharacter
: '!'
;
DoubleTypeCharacter
: '#'
;
StringTypeCharacter
: '$'
;
Se una dichiarazione include un carattere di tipo, il carattere di tipo deve essere d'accordo con il tipo specificato nella dichiarazione stessa; in caso contrario, si verifica un errore in fase di compilazione. Se la dichiarazione omette il tipo , ad esempio se non specifica una As clausola, il carattere di tipo viene sostituito in modo implicito come tipo della dichiarazione.
Non possono venire spazi vuoti tra un identificatore e il relativo carattere di tipo. Non sono presenti caratteri di tipo per Byte, SByte, ShortUShort, UInteger o ULong, a causa di una mancanza di caratteri adatti.
L'aggiunta di un carattere di tipo a un identificatore che concettualmente non ha un tipo (ad esempio, un nome dello spazio dei nomi) o a un identificatore il cui tipo non è d'accordo con il tipo del carattere di tipo genera un errore in fase di compilazione.
L'esempio seguente illustra l'uso di caratteri di tipo:
' 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
Il carattere ! di tipo presenta un problema speciale in quanto può essere usato sia come carattere di tipo che come separatore nella lingua. Per rimuovere ambiguità, un ! carattere è un carattere di tipo purché il carattere che segue non possa avviare un identificatore. Se possibile, il ! carattere è un separatore, non un carattere di tipo.
Parole chiave
Una parola chiave è una parola che ha un significato speciale in un costrutto di linguaggio. Tutte le parole chiave sono riservate dalla lingua e non possono essere usate come identificatori, a meno che gli identificatori non siano preceduti da caratteri di escape.
Nota.EndIf, GoSub, Let, Variante Wend vengono mantenuti come parole chiave, anche se non vengono più usati in 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'
;
Valori letterali
Un valore letterale è una rappresentazione testuale di un determinato valore di un tipo. I tipi letterali includono Boolean, Integer, a virgola mobile, stringa, carattere e data.
Literal
: BooleanLiteral
| IntegerLiteral
| FloatingPointLiteral
| StringLiteral
| CharacterLiteral
| DateLiteral
| Nothing
;
Valori letterali booleani
True e False sono valori letterali del Boolean tipo che eseguono il mapping rispettivamente allo stato true e false.
BooleanLiteral
: 'True' | 'False'
;
Valori letterali integer
I valori letterali integer possono essere decimali (base 10), esadecimali (base 16) o ottale (base 8). Un valore letterale integer decimale è una stringa di cifre decimali (0-9). Un valore letterale esadecimale è &H seguito da una stringa di cifre esadecimali (0-9, A-F). Un valore letterale ottale è &O seguito da una stringa di cifre ottali (0-7). I valori letterali decimali rappresentano direttamente il valore decimale del valore letterale integrale, mentre i valori letterali ottali ed esadecimali rappresentano il valore binario del valore letterale integer (pertanto, &H8000S è -32768, non un errore di overflow).
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'
;
Il tipo di un valore letterale è determinato dal relativo valore o dal carattere di tipo seguente. Se non viene specificato alcun carattere di tipo, i valori nell'intervallo del tipo vengono tipizzati come Integer; i valori al di Integer fuori dell'intervallo per Integer vengono tipizzati come Long. Se il tipo di un valore letterale integer è di dimensioni insufficienti per contenere il valore letterale integer, viene restituito un errore in fase di compilazione. (Nota. Non esiste un carattere di tipo per Byte perché il carattere più naturale sarebbe B, che è un carattere legale in un valore letterale esadecimale.
valori letterali Floating-Point
Un valore letterale a virgola mobile è un valore letterale integer seguito da un separatore decimale facoltativo (il carattere punto ASCII) e una mantissa e un esponente di base 10 facoltativo. Per impostazione predefinita, un valore letterale a virgola mobile è di tipo Double. Se viene specificato il Singlecarattere di tipo , Doubleo Decimal , il valore letterale è di tale tipo. Se il tipo di un valore letterale a virgola mobile è di dimensioni insufficienti per contenere il valore letterale a virgola mobile, viene restituito un errore in fase di compilazione.
Nota. Vale la pena notare che il Decimal tipo di dati può codificare zeri finali in un valore. La specifica attualmente non indica se gli zeri finali in un Decimal valore letterale devono essere rispettati da un compilatore.
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
: '+'
| '-'
;
Letterali di stringa
Un valore letterale stringa è una sequenza di zero o più caratteri Unicode che iniziano e terminano con un carattere virgolette doppie ASCII, un carattere di virgolette doppie Unicode a sinistra o un carattere virgolette doppie Unicode. All'interno di una stringa, una sequenza di due caratteri virgolette doppie è una sequenza di escape che rappresenta una virgoletta doppia nella stringa.
StringLiteral
: DoubleQuoteCharacter StringCharacter* DoubleQuoteCharacter
;
DoubleQuoteCharacter
: '"'
| '<unicode left double-quote 0x201c>'
| '<unicode right double-quote 0x201D>'
;
StringCharacter
: '<Any character except DoubleQuoteCharacter>'
| DoubleQuoteCharacter DoubleQuoteCharacter
;
Una costante stringa è del String tipo .
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
Il compilatore può sostituire un'espressione stringa costante con un valore letterale stringa. Una nuova istanza di stringa non è necessariamente creata per ogni stringa letterale. Quando due o più valori letterali stringa equivalenti in base all'operatore di uguaglianza di stringhe usando la semantica di confronto binario vengono visualizzati nello stesso programma, questi valori letterali stringa possono fare riferimento alla stessa istanza di stringa. Ad esempio, l'output del programma seguente può restituire True perché i due valori letterali possono fare riferimento alla stessa istanza di stringa.
Module Test
Sub Main()
Dim a As Object = "he" & "llo"
Dim b As Object = "hello"
Console.WriteLine(a Is b)
End Sub
End Module
Valori letterali carattere
Un valore letterale carattere rappresenta un singolo carattere Unicode del Char tipo. Due caratteri virgolette doppie è una sequenza di escape che rappresenta il carattere virgolette doppie.
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
Valori letterali data
Un valore letterale data rappresenta un determinato momento nel tempo espresso come valore del Date tipo.
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'
;
Il valore letterale può specificare sia una data che un'ora, solo una data o solo un'ora. Se il valore della data viene omesso, verrà assunto il 1° gennaio dell'anno 1 nel calendario gregoriano. Se il valore di ora viene omesso, si presuppone che venga assunto il valore 12:00:00 AM.
Per evitare problemi con l'interpretazione del valore dell'anno in un valore di data, il valore dell'anno non può essere di due cifre. Quando si esprime una data nel primo secolo AD/CE, è necessario specificare zeri iniziali.
È possibile specificare un valore di ora usando un valore di 24 ore o un valore di 12 ore; i valori di ora che omettono o AMPM sono considerati valori di 24 ore. Se un valore di ora omette i minuti, il valore letterale 0 viene usato per impostazione predefinita. Se un valore di ora omette i secondi, il valore letterale 0 viene usato per impostazione predefinita. Se vengono omessi sia minuti che secondi, AM è necessario specificare o PM . Se il valore di data specificato non è compreso nell'intervallo del Date tipo, si verifica un errore in fase di compilazione.
L'esempio seguente contiene diversi valori letterali data.
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.
Niente
Nothing è un valore letterale speciale; non dispone di un tipo ed è convertibile in tutti i tipi del sistema di tipi, inclusi i parametri di tipo. Quando viene convertito in un particolare tipo, è l'equivalente del valore predefinito di tale tipo.
Nothing
: 'Nothing'
;
Separatori
I caratteri ASCII seguenti sono separatori:
Separator
: '(' | ')' | '{' | '}' | '!' | '#' | ',' | '.' | ':' | '?'
;
Caratteri operatore
I caratteri ASCII o le sequenze di caratteri seguenti indicano gli operatori:
Operator
: '&' | '*' | '+' | '-' | '/' | '\\' | '^' | '<' | '=' | '>'
;
Visual Basic language spec