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.
Dopo l'analisi lessicale di un file, si verificano diversi tipi di pre-elaborazione di origine. La compilazione condizionale più importante determina quale origine viene elaborata dalla grammatica sintattica; due altri tipi di direttive, ovvero direttive di origine esterna e direttive di area, forniscono meta-informazioni sull'origine, ma non hanno alcun effetto sulla compilazione.
Compilazione condizionale
La compilazione condizionale controlla se le sequenze di righe logiche vengono convertite in codice effettivo. All'inizio della compilazione condizionale, tutte le righe logiche sono abilitate; Tuttavia, racchiudere le righe nelle istruzioni di compilazione condizionale può disabilitare selettivamente tali righe all'interno del file, causandone l'ignorare durante il resto del processo di compilazione.
CCStart
: CCStatement*
;
CCStatement
: CCConstantDeclaration
| CCIfGroup
| LogicalLine
;
CCExpression
: LiteralExpression
| CCParenthesizedExpression
| CCSimpleNameExpression
| CCCastExpression
| CCOperatorExpression
| CCConditionalExpression
;
CCParenthesizedExpression
: '(' CCExpression ')'
;
CCSimpleNameExpression
: Identifier
;
CCCastExpression
: 'DirectCast' '(' CCExpression ',' TypeName ')'
| 'TryCast' '(' CCExpression ',' TypeName ')'
| 'CType' '(' CCExpression ',' TypeName ')'
| CastTarget '(' CCExpression ')'
;
CCOperatorExpression
: CCUnaryOperator CCExpression
| CCExpression CCBinaryOperator CCExpression
;
CCUnaryOperator
: '+' | '-' | 'Not'
;
CCBinaryOperator
: '+' | '-' | '*' | '/' | '\\' | 'Mod' | '^' | '='
| '<' '>' | '<' | '>' | '<' '=' | '>' '=' | '&'
| 'And' | 'Or' | 'Xor' | 'AndAlso' | 'OrElse'
| '<' '<' | '>' '>'
;
CCConditionalExpression
: 'If' '(' CCExpression ',' CCExpression ',' CCExpression ')'
| 'If' '(' CCExpression ',' CCExpression ')'
;
Ad esempio, il programma
#Const A = True
#Const B = False
Class C
#If A Then
Sub F()
End Sub
#Else
Sub G()
End Sub
#End If
#If B Then
Sub H()
End Sub
#Else
Sub I()
End Sub
#End If
End Class
produce la stessa sequenza di token del programma
Class C
Sub F()
End Sub
Sub I()
End Sub
End Class
Le espressioni costanti consentite nelle direttive di compilazione condizionale sono un subset di espressioni costanti generali.
Il preprocessore consente spazi vuoti e continuazioni di riga esplicite prima e dopo ogni token.
Direttive costanti condizionali
Le istruzioni costanti condizionali definiscono costanti presenti in uno spazio di dichiarazione di compilazione condizionale separato con ambito nel file di origine.
CCConstantDeclaration
: '#' 'Const' Identifier '=' CCExpression LineTerminator
;
Lo spazio di dichiarazione è speciale in quanto non è necessaria alcuna dichiarazione esplicita delle costanti di compilazione condizionale. Le costanti condizionali possono essere definite in modo implicito in una direttiva di compilazione condizionale.
Prima di assegnare un valore, una costante di compilazione condizionale ha il valore Nothing. Quando a una costante di compilazione condizionale viene assegnato un valore, che deve essere un'espressione costante, il tipo della costante diventa il tipo del valore assegnato. Una costante di compilazione condizionale può essere ridefinita più volte in un file di origine.
Ad esempio, il codice seguente stampa solo la stringa about to print value e il valore di Test.
Module M1
Sub PrintValue(Test As Integer)
#Const DebugCode = True
#If DebugCode Then
Console.WriteLine("about to print value")
#End If
#Const DebugCode = False
Console.WriteLine(Test)
#If DebugCode Then
Console.WriteLine("printed value")
#End If
End Sub
End Module
L'ambiente di compilazione può anche definire costanti condizionali in uno spazio di dichiarazione di compilazione condizionale.
Direttive di compilazione condizionale
Le direttive di compilazione condizionale controllano la compilazione condizionale.
CCIfGroup
: '#' 'If' CCExpression 'Then'? LineTerminator CCStatement*
CCElseIfGroup* CCElseGroup? '#' 'End' 'If' LineTerminator
;
CCElseIfGroup
: '#' ElseIf CCExpression 'Then'? LineTerminator CCStatement*
;
CCElseGroup
: '#' 'Else' LineTerminator CCStatement*
;
Le costanti condizionali possono fare riferimento solo a espressioni costanti e costanti di compilazione condizionale. Ognuna delle espressioni costanti all'interno di un singolo gruppo di compilazione condizionale viene valutata e convertita nel Boolean tipo in ordine testuale dal primo all'ultimo fino a quando una delle espressioni condizionali restituisce True. Se un'espressione non è convertibile in Boolean, viene restituito un errore in fase di compilazione. La semantica permissiva e i confronti di stringhe binarie vengono sempre usati durante la valutazione delle espressioni costanti di compilazione condizionale, indipendentemente dalle direttive o dalle impostazioni dell'ambiente di Option compilazione.
Tutte le righe racchiuse dal gruppo, incluse le direttive di compilazione condizionale annidate, sono disabilitate, ad eccezione delle righe tra l'istruzione contenente l'espressione True e l'istruzione condizionale successiva del gruppo o le righe tra l'istruzione Else e l'istruzione End If se Else viene visualizzato nel gruppo e tutte le espressioni restituiscono False.
In questo esempio la chiamata a WriteToLog nella direttiva di Trace compilazione condizionale non viene elaborata perché la direttiva di compilazione condizionale circostante Debug restituisce False.
#Const Debug = False ' Debugging off
#Const Trace = True ' Tracing on
Class PurchaseTransaction
Sub Commit()
#If Debug Then
CheckConsistency()
#If Trace Then
WriteToLog(Me.ToString())
#End If
#End If
...
End Sub
End Class
Direttive di origine esterna
Un file di origine può includere direttive di origine esterne che indicano un mapping tra le righe di origine e il testo esterno all'origine.
ESDStart
: ExternalSourceStatement*
;
ExternalSourceStatement
: ExternalSourceGroup
| LogicalLine
;
ExternalSourceGroup
: '#' 'ExternalSource' '(' StringLiteral ',' IntLiteral ')' LineTerminator
LogicalLine* '#' 'End' 'ExternalSource' LineTerminator
;
Le direttive di origine esterna non hanno alcun effetto sulla compilazione e potrebbero non essere annidate. Per esempio:
Module Test
Sub Main()
#ExternalSource("c:\wwwroot\inetpub\test.aspx", 30)
Console.WriteLine("In test.aspx")
#End ExternalSource
End Sub
End Module
Direttive region
Le direttive region raggruppano righe di codice sorgente, ma non hanno altro effetto sulla compilazione. L'intero gruppo può essere compresso e nascosto o espanso e visualizzato nell'ambiente di sviluppo integrato (IDE).
RegionStart
: RegionStatement*
;
RegionStatement
: RegionGroup
| LogicalLine
;
RegionGroup
: '#' 'Region' StringLiteral LineTerminator
RegionStatement*
'#' 'End' 'Region' LineTerminator
;
Le aree possono essere annidate. Le direttive region sono speciali in quanto non possono né iniziare né terminare all'interno di un corpo del metodo e devono rispettare la struttura del blocco del programma. Per esempio:
Module Test
#Region "Startup code - do not edit"
Sub Main()
End Sub
#End Region
End Module
' Error due to Region directives breaking the block structure
Class C
#Region "Fred"
End Class
#End Region
Direttive checksum esterne
Un file di origine può includere una direttiva checksum esterna che indica quale checksum deve essere generato per un file a cui viene fatto riferimento in una direttiva di origine esterna. In tutti gli altri aspetti, le direttive di origine esterna non hanno alcun effetto sulla compilazione.
ExternalChecksumStart
: ExternalChecksumStatement*
;
ExternalChecksumStatement
: '#' 'ExternalChecksum' '('
StringLiteral ',' StringLiteral ',' StringLiteral
')' LineTerminator
;
Una direttiva checksum esterna contiene il nome file del file esterno, un identificatore univoco globale (GUID) associato al file e il checksum per il file. Il GUID viene specificato come costante stringa del formato "{xxxxxxxx-xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}", dove x è una cifra esadecimale. Il checksum viene specificato come costante stringa del formato "xxxx...", dove x è una cifra esadecimale. Il numero di cifre in un checksum deve essere un numero pari.
A un file esterno possono essere associate più direttive checksum esterne, a condizione che tutti i valori GUID e checksum corrispondano esattamente. Se il nome del file esterno corrisponde al nome di un file compilato, il checksum viene ignorato a favore del calcolo del checksum del compilatore.
Per esempio:
#ExternalChecksum("c:\wwwroot\inetpub\test.aspx", _
"{12345678-1234-1234-1234-123456789abc}", _
"1a2b3c4e5f617239a49b9a9c0391849d34950f923fab9484")
Module Test
Sub Main()
#ExternalSource("c:\wwwroot\inetpub\test.aspx", 30)
Console.WriteLine("In test.aspx")
#End ExternalSource
End Sub
End Module
Visual Basic language spec