Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La compilación de un programa de Visual Basic implica primero traducir la secuencia sin procesar de caracteres Unicode en un conjunto ordenado de tokens léxicos. Dado que el lenguaje de Visual Basic no tiene formato libre, el conjunto de tokens se divide en una serie de líneas lógicas. Una línea lógica abarca desde el inicio de la secuencia o un terminador de línea hasta el terminador de línea siguiente que no va precedido por una continuación de línea o hasta el final de la secuencia.
Nota. Con la introducción de expresiones literales XML en la versión 9.0 del lenguaje, Visual Basic ya no tiene una gramática léxica distinta en el sentido de que el código de Visual Basic se puede tokenizar sin tener en cuenta el contexto sintáctico. Esto se debe a que XML y Visual Basic tienen reglas léxicas diferentes y el conjunto de reglas léxicas en uso en cualquier momento determinado depende de la construcción sintáctica que se está procesando en ese momento. Esta especificación conserva esta sección de gramática léxica como guía de las reglas léxicas del código normal de Visual Basic.
LogicalLineStart
: LogicalLine*
;
LogicalLine
: LogicalLineElement* Comment? LineTerminator
;
LogicalLineElement
: WhiteSpace
| LineContinuation
| Token
;
Token
: Identifier
| Keyword
| Literal
| Separator
| Operator
;
Caracteres y líneas
Los programas de Visual Basic se componen de caracteres del juego de caracteres Unicode.
Character:
'<Any Unicode character except a LineTerminator>'
;
Terminadores de línea
Los caracteres de salto de línea Unicode separan las líneas lógicas.
LineTerminator
: '<Unicode 0x00D>'
| '<Unicode 0x00A>'
| '<CR>'
| '<LF>'
| '<Unicode 0x2028>'
| '<Unicode 0x2029>'
;
Continuación de línea
Una continuación de línea consta de al menos un carácter de espacio en blanco que precede inmediatamente a un carácter de subrayado único como último carácter (distinto del espacio en blanco) en una línea de texto. Una continuación de línea permite que una línea lógica abarque más de una línea física. Las continuaciones de línea se tratan como si fueran espacios en blanco, aunque no lo sean.
LineContinuation
: WhiteSpace '_' WhiteSpace* LineTerminator
;
En el siguiente programa se muestran algunas continuaciones de línea:
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
Algunos lugares de la gramática sintáctica permiten continuaciones de línea implícitas. Cuando se encuentra un terminador de línea
después de una coma (
,), paréntesis abierto ((), llave abierta ({) o expresión incrustada abierta (<%=)después de un calificador de miembro (
.o.@...), siempre que se califica algo (es decir, no está usando un contexto implícitoWith)antes de un paréntesis de cierre (
)), cierre llave (}) o cierre la expresión insertada (%>)después de un valor menor que (
<) en un contexto de atributoantes de un valor mayor que (
>) en un contexto de atributodespués de un valor mayor que (
>) en un contexto de atributo que no sea de nivel de archivoantes y después de los operadores de consulta (
Where,Order,Select, etc.)después de los operadores binarios (
+,-,/,*, etc.) en un contexto de expresióndespués de los operadores de asignación (
=,:=,+=,-=, etc.) en cualquier contexto.
el terminador de línea se trata como si fuera una continuación de línea.
Comma
: ',' LineTerminator?
;
Period
: '.' LineTerminator?
;
OpenParenthesis
: '(' LineTerminator?
;
CloseParenthesis
: LineTerminator? ')'
;
OpenCurlyBrace
: '{' LineTerminator?
;
CloseCurlyBrace
: LineTerminator? '}'
;
Equals
: '=' LineTerminator?
;
ColonEquals
: ':' '=' LineTerminator?
;
Por ejemplo, el ejemplo anterior también podría escribirse como:
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
Las continuaciones de línea implícitas solo se deducirán directamente antes o después del token especificado. No se deducirán antes o después de una continuación de línea. Por ejemplo:
Dim y = 10
' Error: Expression expected for assignment to x
Dim x = _
y
Las continuaciones de línea no se deducirán en contextos de compilación condicionales. (Nota. Esta última restricción es necesaria porque el texto de los bloques de compilación condicional que no están compilados no tiene que ser válido sintácticamente. Por lo tanto, el texto del bloque podría "recogerse accidentalmente" por la instrucción de compilación condicional, especialmente cuando el lenguaje se extiende en el futuro).
Espacio en blanco
El espacio en blanco solo sirve para separar los tokens y, de lo contrario, se omite. Las líneas lógicas que solo contienen espacios en blanco se omiten. (Nota. Los terminadores de línea no se consideran espacios en blanco).
WhiteSpace
: '<Unicode class Zs>'
| '<Unicode Tab 0x0009>'
;
Comentarios
Un comentario comienza con un carácter de comillas simples o la palabra clave REM. Un carácter de comilla simple es un carácter de comillas simples ASCII, un carácter de comilla simple izquierda Unicode o un carácter de comilla simple derecha Unicode. Los comentarios pueden comenzar en cualquier lugar de una línea de origen y el final de la línea física finaliza el comentario. El compilador omite los caracteres entre el principio del comentario y el terminador de línea. Por lo tanto, los comentarios no se pueden extender entre varias líneas mediante continuaciones de línea.
Comment
: CommentMarker Character*
;
CommentMarker
: SingleQuoteCharacter
| 'REM'
;
SingleQuoteCharacter
: '\''
| '<Unicode 0x2018>'
| '<Unicode 0x2019>'
;
Identificadores
Un identificador es un nombre. Los identificadores de Visual Basic se ajustan al Anexo 15 Estándar Unicode con una excepción: los identificadores pueden comenzar con un carácter de subrayado (conector). Si un identificador comienza con un carácter de subrayado, debe contener al menos otro carácter de identificador válido para desambiguarlo de una continuación de línea.
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
;
Es posible que los identificadores regulares no coincidan con palabras clave, pero los identificadores o identificadores con escape con un carácter de tipo pueden. Un identificador de escape es un identificador delimitado por corchetes. Los identificadores con escape siguen las mismas reglas que los identificadores normales, excepto que pueden coincidir con palabras clave y pueden no tener caracteres de tipo.
En este ejemplo se define una clase denominada class con un método compartido denominado shared que toma un parámetro denominado boolean y, a continuación, llama al método .
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
Los identificadores no distinguen mayúsculas de minúsculas, por lo que se considera que dos identificadores son iguales si solo difieren en el caso. (Nota. Las asignaciones de mayúsculas y minúsculas estándar Unicode estándar se usan al comparar identificadores y se omiten las asignaciones de mayúsculas y minúsculas específicas de la configuración regional).
Caracteres de tipo
Un carácter de tipo indica el tipo del identificador anterior. El carácter de tipo no se considera parte del identificador.
TypeCharacter
: IntegerTypeCharacter
| LongTypeCharacter
| DecimalTypeCharacter
| SingleTypeCharacter
| DoubleTypeCharacter
| StringTypeCharacter
;
IntegerTypeCharacter
: '%'
;
LongTypeCharacter
: '&'
;
DecimalTypeCharacter
: '@'
;
SingleTypeCharacter
: '!'
;
DoubleTypeCharacter
: '#'
;
StringTypeCharacter
: '$'
;
Si una declaración incluye un carácter de tipo, el carácter de tipo debe estar de acuerdo con el tipo especificado en la propia declaración; De lo contrario, se produce un error en tiempo de compilación. Si la declaración omite el tipo (por ejemplo, si no especifica una As cláusula), el carácter de tipo se sustituye implícitamente como el tipo de la declaración.
No puede haber ningún espacio en blanco entre un identificador y su carácter de tipo. No hay caracteres de tipo para Byte, SByte, UShort, Shorto ULongUInteger , debido a la falta de caracteres adecuados.
Anexar un carácter de tipo a un identificador que conceptualmente no tiene un tipo (por ejemplo, un nombre de espacio de nombres) o a un identificador cuyo tipo no está de acuerdo con el tipo del carácter de tipo provoca un error en tiempo de compilación.
En el ejemplo siguiente se muestra el uso de caracteres de 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
El carácter ! de tipo presenta un problema especial en que se puede usar como carácter de tipo y como separador en el idioma. Para quitar la ambigüedad, un ! carácter es un carácter de tipo siempre que el carácter que sigue no pueda iniciar un identificador. Si es posible, el ! carácter es un separador, no un carácter de tipo.
Palabras clave
Una palabra clave es una palabra que tiene un significado especial en una construcción de lenguaje. Todas las palabras clave están reservadas por el idioma y no se pueden usar como identificadores a menos que se escapen los identificadores. (Note.EndIf, GoSub, Let, Varianty Wend se conservan como palabras clave, aunque ya no se usan en 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'
;
Literales
Un literal es una representación textual de un valor determinado de un tipo. Los tipos literales incluyen booleano, entero, punto flotante, cadena, carácter y fecha.
Literal
: BooleanLiteral
| IntegerLiteral
| FloatingPointLiteral
| StringLiteral
| CharacterLiteral
| DateLiteral
| Nothing
;
Literales booleanos
True y False son literales del Boolean tipo que se asignan al estado true y false, respectivamente.
BooleanLiteral
: 'True' | 'False'
;
Literales enteros
Los literales enteros pueden ser decimales (base 10), hexadecimales (base 16) o octales (base 8). Un literal entero decimal es una cadena de dígitos decimales (0-9). Un literal hexadecimal va &H seguido de una cadena de dígitos hexadecimales (0-9, A-F). Un literal octal va &O seguido de una cadena de dígitos octales (0-7). Los literales decimales representan directamente el valor decimal del literal entero, mientras que los literales octales y hexadecimales representan el valor binario del literal entero (por lo tanto, &H8000S es -32768, no un error de desbordamiento).
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'
;
El tipo de un literal viene determinado por su valor o por el siguiente carácter de tipo. Si no se especifica ningún carácter de tipo, los valores del intervalo del Integer tipo se escriben como Integer; los valores fuera del intervalo para Integer se escriben como Long. Si el tipo del literal entero es de tamaño insuficiente para contener el literal entero, se produce un error en tiempo de compilación. (Nota. No hay un carácter de tipo para Byte porque el carácter más natural sería B, que es un carácter legal en un literal hexadecimal).
literales de Floating-Point
Un literal de punto flotante es un literal entero seguido de un separador decimal opcional (el carácter de punto ASCII) y la mantisa, y un exponente base 10 opcional. De forma predeterminada, un literal de punto flotante es de tipo Double. Si se especifica el Singlecarácter de tipo , Doubleo Decimal , el literal es de ese tipo. Si el tipo de literal de punto flotante es de tamaño insuficiente para contener el literal de punto flotante, se produce un error en tiempo de compilación.
Nota. Vale la pena tener en cuenta que el Decimal tipo de datos puede codificar ceros finales en un valor. Actualmente, la especificación no hace ningún comentario sobre si un compilador debe respetar los ceros finales de un Decimal literal.
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
: '+'
| '-'
;
Literales de cadena
Un literal de cadena es una secuencia de cero o más caracteres Unicode que comienzan y terminan con un carácter de comilla doble ASCII, un carácter de comilla doble izquierda Unicode o un carácter de comilla doble a la derecha Unicode. Dentro de una cadena, una secuencia de dos caracteres de comillas dobles es una secuencia de escape que representa una comilla doble en la cadena.
StringLiteral
: DoubleQuoteCharacter StringCharacter* DoubleQuoteCharacter
;
DoubleQuoteCharacter
: '"'
| '<unicode left double-quote 0x201c>'
| '<unicode right double-quote 0x201D>'
;
StringCharacter
: '<Any character except DoubleQuoteCharacter>'
| DoubleQuoteCharacter DoubleQuoteCharacter
;
Una constante de cadena es 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
El compilador puede reemplazar una expresión de cadena constante por un literal de cadena. Cada literal de cadena no produce necesariamente una nueva instancia de cadena. Cuando dos o más literales de cadena equivalentes según el operador de igualdad de cadenas mediante la semántica de comparación binaria aparecen en el mismo programa, estos literales de cadena pueden hacer referencia a la misma instancia de cadena. Por ejemplo, la salida del siguiente programa puede devolverse True porque los dos literales pueden hacer referencia a la misma instancia de cadena.
Module Test
Sub Main()
Dim a As Object = "he" & "llo"
Dim b As Object = "hello"
Console.WriteLine(a Is b)
End Sub
End Module
Literales de caracteres
Un literal de carácter representa un único carácter Unicode del Char tipo. Dos caracteres de comillas dobles es una secuencia de escape que representa el carácter de comillas dobles.
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
Literales de fecha
Un literal de fecha representa un momento determinado en el tiempo expresado como un valor 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'
;
El literal puede especificar una fecha y una hora, solo una fecha o solo una hora. Si se omite el valor de fecha, se asume el 1 de enero del año 1 en el calendario gregoriano. Si se omite el valor de hora, se asume 12:00:00 AM.
Para evitar problemas al interpretar el valor de año en un valor de fecha, el valor de año no puede ser de dos dígitos. Al expresar una fecha en el primer siglo AD/CE, se deben especificar ceros iniciales.
Se puede especificar un valor de hora mediante un valor de 24 horas o un valor de 12 horas; valores de hora que omiten AM o PM se supone que son valores de 24 horas. Si un valor de hora omite los minutos, el literal 0 se usa de forma predeterminada. Si un valor de hora omite los segundos, el literal 0 se usa de forma predeterminada. Si se omiten los minutos y el segundo, AM o PM debe especificarse. Si el valor de fecha especificado está fuera del intervalo del Date tipo, se produce un error en tiempo de compilación.
En el ejemplo siguiente se incluyen varios literales de fecha.
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.
Nada
Nothing es un literal especial; no tiene un tipo y se puede convertir a todos los tipos del sistema de tipos, incluidos los parámetros de tipo. Cuando se convierte en un tipo determinado, es el equivalente del valor predeterminado de ese tipo.
Nothing
: 'Nothing'
;
Separadores
Los siguientes caracteres ASCII son separadores:
Separator
: '(' | ')' | '{' | '}' | '!' | '#' | ',' | '.' | ':' | '?'
;
Caracteres de operador
Los siguientes caracteres ASCII o secuencias de caracteres indican operadores:
Operator
: '&' | '*' | '+' | '-' | '/' | '\\' | '^' | '<' | '=' | '>'
;
Visual Basic language spec