Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
La compilation d’un programme Visual Basic implique d’abord de traduire le flux brut de caractères Unicode en un ensemble ordonné de jetons lexicals. Étant donné que le langage Visual Basic n’est pas au format libre, l’ensemble de jetons est ensuite divisé en une série de lignes logiques. Une ligne logique s’étend du début du flux ou d’un terminateur de ligne jusqu’à l’indicateur de fin de ligne suivant qui n’est pas précédé d’une continuation de ligne ou jusqu’à la fin du flux.
Remarque. Avec l’introduction d’expressions littérales XML dans la version 9.0 du langage, Visual Basic n’a plus de grammaire lexicale distincte dans le sens où le code Visual Basic peut être tokenisé sans tenir compte du contexte syntaxique. Cela est dû au fait que XML et Visual Basic ont des règles lexicales différentes et que l’ensemble de règles lexicales en cours d’utilisation à tout moment dépend de la construction syntaxique en cours de traitement à ce moment-là. Cette spécification conserve cette section de grammaire lexicale comme guide des règles lexicales du code Visual Basic standard.
LogicalLineStart
: LogicalLine*
;
LogicalLine
: LogicalLineElement* Comment? LineTerminator
;
LogicalLineElement
: WhiteSpace
| LineContinuation
| Token
;
Token
: Identifier
| Keyword
| Literal
| Separator
| Operator
;
Caractères et lignes
Les programmes Visual Basic sont composés de caractères du jeu de caractères Unicode.
Character:
'<Any Unicode character except a LineTerminator>'
;
Terminateurs de ligne
Les caractères de saut de ligne Unicode séparent les lignes logiques.
LineTerminator
: '<Unicode 0x00D>'
| '<Unicode 0x00A>'
| '<CR>'
| '<LF>'
| '<Unicode 0x2028>'
| '<Unicode 0x2029>'
;
Continuation de ligne
Une continuation de ligne se compose d’au moins un caractère d’espace blanc qui précède immédiatement un caractère de soulignement unique comme dernier caractère (autre que l’espace blanc) dans une ligne de texte. Une continuation de ligne permet à une ligne logique d’étendre plusieurs lignes physiques. Les continuations de lignes sont traitées comme si elles étaient des espaces blancs, même si elles ne le sont pas.
LineContinuation
: WhiteSpace '_' WhiteSpace* LineTerminator
;
Le programme suivant présente quelques continuations de ligne :
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
Certains endroits de la grammaire syntaxique permettent des continuations de lignes implicites. Lorsqu’un terminateur de ligne est rencontré
après une virgule (
,), une parenthèse ouverte ((), une accolade ouverte ({) ou une expression incorporée ouverte (<%=)après un qualificateur de membre (
.ou.@...), à condition que quelque chose soit qualifié (c’est-à-dire qu’il n’utilise pas de contexte impliciteWith)avant une parenthèse proche (
)), accolades proches (}) ou fermer l’expression incorporée (%>)après une valeur inférieure à (
<) dans un contexte d’attributavant un () supérieur à (
>) dans un contexte d’attributaprès un () supérieur à (
>) dans un contexte d’attribut de niveau non fichieropérateurs de requête avant et après (
Where,Order,Select, etc.)après les opérateurs binaires (
+, ,-/,*etc.) dans un contexte d’expressionaprès les opérateurs d’affectation (
=, ,:=,+=-=etc.) dans n’importe quel contexte.
le terminateur de ligne est traité comme s’il s’agissait d’une continuation de ligne.
Comma
: ',' LineTerminator?
;
Period
: '.' LineTerminator?
;
OpenParenthesis
: '(' LineTerminator?
;
CloseParenthesis
: LineTerminator? ')'
;
OpenCurlyBrace
: '{' LineTerminator?
;
CloseCurlyBrace
: LineTerminator? '}'
;
Equals
: '=' LineTerminator?
;
ColonEquals
: ':' '=' LineTerminator?
;
Par exemple, l’exemple précédent peut également être écrit comme suit :
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
Les continuations de ligne implicites ne seront déduites que directement avant ou après le jeton spécifié. Ils ne seront pas déduits avant ou après une continuation de ligne. Par exemple:
Dim y = 10
' Error: Expression expected for assignment to x
Dim x = _
y
Les continuations de ligne ne seront pas déduites dans les contextes de compilation conditionnelle. (Remarque. Cette dernière restriction est requise, car le texte dans les blocs de compilation conditionnel qui ne sont pas compilés n’a pas besoin d’être syntactiquement valide. Par conséquent, le texte du bloc peut accidentellement être « récupéré » par l’instruction de compilation conditionnelle, en particulier lorsque la langue est étendue à l’avenir.)
Espace blanc
L’espace blanc sert uniquement à séparer les jetons et est sinon ignoré. Les lignes logiques contenant uniquement des espaces blancs sont ignorées. (Remarque. Les terminateurs de ligne ne sont pas considérés comme des espaces blancs.)
WhiteSpace
: '<Unicode class Zs>'
| '<Unicode Tab 0x0009>'
;
Commentaires
Un commentaire commence par un caractère de guillemet unique ou le mot clé REM. Un caractère à guillemet unique est un caractère de guillemet unique ASCII, un caractère de guillemet unique Unicode gauche ou un caractère de guillemet unique Unicode à droite. Les commentaires peuvent commencer n’importe où sur une ligne source et la fin de la ligne physique termine le commentaire. Le compilateur ignore les caractères entre le début du commentaire et le point de fin de ligne. Par conséquent, les commentaires ne peuvent pas s’étendre sur plusieurs lignes à l’aide de continuations de ligne.
Comment
: CommentMarker Character*
;
CommentMarker
: SingleQuoteCharacter
| 'REM'
;
SingleQuoteCharacter
: '\''
| '<Unicode 0x2018>'
| '<Unicode 0x2019>'
;
Identificateurs
Un identificateur est un nom. Les identificateurs Visual Basic sont conformes à l’annexe 15 standard Unicode avec une exception : les identificateurs peuvent commencer par un caractère de trait de soulignement (connecteur). Si un identificateur commence par un trait de soulignement, il doit contenir au moins un autre caractère d’identificateur valide pour le lever de l’ambiguïté d’une continuation de ligne.
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
;
Les identificateurs réguliers peuvent ne pas correspondre aux mots clés, mais les identificateurs ou les identificateurs échappés avec un caractère de type peuvent. Un identificateur d’échappement est un identificateur délimité par des crochets. Les identificateurs échappés suivent les mêmes règles que les identificateurs réguliers, sauf qu’ils peuvent correspondre à des mots clés et qu’ils n’ont peut-être pas de caractères de type.
Cet exemple définit une classe nommée class avec une méthode partagée nommée shared qui prend un paramètre nommé boolean , puis appelle la méthode.
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
Les identificateurs ne respectent pas la casse, donc deux identificateurs sont considérés comme identiques s’ils diffèrent uniquement dans le cas. (Remarque. Les mappages de cas un-à-un standard Unicode sont utilisés lors de la comparaison des identificateurs et des mappages de cas spécifiques aux paramètres régionaux sont ignorés.)
Caractères de type
Un caractère de type indique le type de l’identificateur précédent. Le caractère de type n’est pas considéré comme faisant partie de l’identificateur.
TypeCharacter
: IntegerTypeCharacter
| LongTypeCharacter
| DecimalTypeCharacter
| SingleTypeCharacter
| DoubleTypeCharacter
| StringTypeCharacter
;
IntegerTypeCharacter
: '%'
;
LongTypeCharacter
: '&'
;
DecimalTypeCharacter
: '@'
;
SingleTypeCharacter
: '!'
;
DoubleTypeCharacter
: '#'
;
StringTypeCharacter
: '$'
;
Si une déclaration inclut un caractère de type, le caractère de type doit être d’accord avec le type spécifié dans la déclaration elle-même ; sinon, une erreur au moment de la compilation se produit. Si la déclaration omet le type (par exemple, s’il ne spécifie pas de As clause), le caractère de type est implicitement substitué comme type de déclaration.
Aucun espace blanc ne peut se trouver entre un identificateur et son caractère de type. Il n’y a pas de caractères de type pour Byte, , SByteUShort, ShortUInteger ou ULong, en raison d’un manque de caractères appropriés.
L’ajout d’un caractère de type à un identificateur qui n’a pas conceptuellement de type (par exemple, un nom d’espace de noms) ou un identificateur dont le type n’est pas d’accord avec le type du caractère de type provoque une erreur au moment de la compilation.
L’exemple suivant montre l’utilisation de caractères de type :
' 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
Le caractère ! de type présente un problème particulier dans lequel il peut être utilisé à la fois comme caractère de type et comme séparateur dans la langue. Pour supprimer l’ambiguïté, un ! caractère est un caractère de type tant que le caractère qui suit ne peut pas démarrer un identificateur. Si c’est possible, le ! caractère est un séparateur, et non un caractère de type.
Mots clés
Un mot clé est un mot qui a une signification particulière dans une construction de langage. Tous les mots clés sont réservés par la langue et peuvent ne pas être utilisés comme identificateurs, sauf si les identificateurs sont placés dans l’échappement. (Remarque.EndIf, GoSub, , VariantLetet Wend sont conservés en tant que mots clés, bien qu’ils ne soient plus utilisés dans 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'
;
Littéraux
Un littéral est une représentation textuelle d’une valeur particulière d’un type. Les types littéraux incluent booléen, entier, virgule flottante, chaîne, caractère et date.
Literal
: BooleanLiteral
| IntegerLiteral
| FloatingPointLiteral
| StringLiteral
| CharacterLiteral
| DateLiteral
| Nothing
;
Littéraux booléens
True et False sont des littéraux du Boolean type qui mappent à l’état true et false, respectivement.
BooleanLiteral
: 'True' | 'False'
;
Littéraux entiers
Les littéraux entiers peuvent être décimaux (base 10), hexadécimaux (base 16) ou octal (base 8). Un littéral entier décimal est une chaîne de chiffres décimaux (0-9). Un littéral hexadécimal est &H suivi d’une chaîne de chiffres hexadécimaux (0-9, A-F). Un littéral octal est &O suivi d’une chaîne de chiffres octal (0-7). Les littéraux décimaux représentent directement la valeur décimale du littéral intégral, tandis que les littéraux octal et hexadécimaux représentent la valeur binaire du littéral entier (par conséquent, &H8000S est -32768, et non une erreur de dépassement de capacité).
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'
;
Le type d’un littéral est déterminé par sa valeur ou par le caractère de type suivant. Si aucun caractère de type n’est spécifié, les valeurs de la Integer plage du type sont typées en tant que Integer; les valeurs en dehors de la plage sont Integer typées comme Long. Si le type d’un littéral entier est de taille insuffisante pour contenir le littéral entier, une erreur au moment de la compilation se produit. (Remarque. Il n’existe pas de caractère de type car Byte le caractère le plus naturel serait B, qui est un caractère légal dans un littéral hexadécimal.)
littéraux Floating-Point
Un littéral à virgule flottante est un littéral entier suivi d’un point décimal facultatif (caractère de point ASCII) et de mantissa, et d’un exposant de base 10 facultatif. Par défaut, un littéral à virgule flottante est de type Double. Si le Singlecaractère , Doubleou Decimal type est spécifié, le littéral est de ce type. Si le type d’un littéral à virgule flottante est insuffisant pour contenir le littéral à virgule flottante, une erreur au moment de la compilation se produit.
Remarque. Il est important de noter que le Decimal type de données peut encoder les zéros de fin dans une valeur. La spécification ne fait actuellement aucun commentaire quant à la fin des zéros dans un Decimal littéral doit être respecté par un compilateur.
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
: '+'
| '-'
;
Littéraux de chaîne
Un littéral de chaîne est une séquence de zéro ou plusieurs caractères Unicode commençant et se terminant par un caractère de guillemets doubles ASCII, un caractère de guillemets doubles de gauche Unicode ou un caractère de guillemets doubles unicode droit. Dans une chaîne, une séquence de deux caractères de guillemets doubles est une séquence d’échappement représentant un guillemet double dans la chaîne.
StringLiteral
: DoubleQuoteCharacter StringCharacter* DoubleQuoteCharacter
;
DoubleQuoteCharacter
: '"'
| '<unicode left double-quote 0x201c>'
| '<unicode right double-quote 0x201D>'
;
StringCharacter
: '<Any character except DoubleQuoteCharacter>'
| DoubleQuoteCharacter DoubleQuoteCharacter
;
Une constante de chaîne est du String type.
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
Le compilateur est autorisé à remplacer une expression de chaîne constante par un littéral de chaîne. Chaque littéral de chaîne n’entraîne pas nécessairement une nouvelle instance de chaîne. Lorsque deux littéraux de chaîne ou plus équivalents selon l’opérateur d’égalité de chaîne à l’aide de la sémantique de comparaison binaire apparaissent dans le même programme, ces littéraux de chaîne peuvent faire référence à la même instance de chaîne. Par exemple, la sortie du programme suivant peut retourner True , car les deux littéraux peuvent faire référence à la même instance de chaîne.
Module Test
Sub Main()
Dim a As Object = "he" & "llo"
Dim b As Object = "hello"
Console.WriteLine(a Is b)
End Sub
End Module
Littéraux de caractères
Un littéral de caractère représente un caractère Unicode unique du Char type. Deux caractères de guillemets doubles sont une séquence d’échappement représentant le caractère de guillemets doubles.
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
Littéraux de date
Un littéral de date représente un moment particulier dans l’heure exprimé sous forme de valeur du Date type.
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'
;
Le littéral peut spécifier à la fois une date et une heure, juste une date ou une heure. Si la valeur de date est omise, le 1er janvier de l’année 1 dans le calendrier grégorien est supposé. Si la valeur de temps est omise, 12:00:00 AM est supposée.
Pour éviter les problèmes liés à l’interprétation de la valeur d’année dans une valeur de date, la valeur de l’année ne peut pas être de deux chiffres. Lors de l’expression d’une date au premier siècle AD/CE, les zéros non significatifs doivent être spécifiés.
Une valeur de temps peut être spécifiée à l’aide d’une valeur de 24 heures ou d’une valeur de 12 heures ; valeurs de temps qui omettent ou AMPM sont supposées être des valeurs de 24 heures. Si une valeur de temps omet les minutes, le littéral 0 est utilisé par défaut. Si une valeur de temps omet les secondes, le littéral 0 est utilisé par défaut. Si les minutes et la seconde sont omises, ou AMPM doivent être spécifiées. Si la valeur de date spécifiée est en dehors de la Date plage du type, une erreur de compilation se produit.
L’exemple suivant contient plusieurs littéraux de 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.
Rien
Nothing est un littéral spécial ; il n’a pas de type et est convertible en tous les types dans le système de type, y compris les paramètres de type. En cas de conversion en type particulier, il s’agit de l’équivalent de la valeur par défaut de ce type.
Nothing
: 'Nothing'
;
Séparateurs
Les caractères ASCII suivants sont des séparateurs :
Separator
: '(' | ')' | '{' | '}' | '!' | '#' | ',' | '.' | ':' | '?'
;
Caractères d’opérateur
Les caractères ASCII ou séquences de caractères suivants désignent les opérateurs :
Operator
: '&' | '*' | '+' | '-' | '/' | '\\' | '^' | '<' | '=' | '>'
;
Visual Basic language spec