Události
Vytváření inteligentních aplikací
17. 3. 23 - 21. 3. 23
Připojte se k řadě meetupů a vytvořte škálovatelná řešení AI založená na skutečných případech použití s kolegy vývojáři a odborníky.
ZaregistrovatTento prohlížeč se už nepodporuje.
Upgradujte na Microsoft Edge, abyste mohli využívat nejnovější funkce, aktualizace zabezpečení a technickou podporu.
Strom syntaxe je základní neměnná datová struktura vystavená rozhraními API kompilátoru. Tyto stromy představují lexikální a syntaktickou strukturu zdrojového kódu. Slouží dvěma důležitým účelům:
Stromy syntaxe jsou primární strukturou používanou k kompilaci, analýze kódu, vazbě, refaktoringu, funkcím ide a generování kódu. Žádná část zdrojového kódu není srozumitelná, aniž by byla nejprve identifikována a kategorizována do některého z mnoha známých prvků strukturálního jazyka.
Poznámka
RoslynQuoter je opensourcový nástroj, který zobrazuje volání rozhraní API pro vytváření syntaxe používané k vytvoření stromu syntaxe programu. Pokud si to chcete vyzkoušet živě, podívejte http://roslynquoter.azurewebsites.netse.
Stromy syntaxe mají tři klíčové atributy:
Strom syntaxe je doslova datová struktura stromu, kde jiné než terminálové strukturální prvky nadřazené jiným prvkům. Každý strom syntaxe se skládá z uzlů, tokenů a trivií.
Uzly syntaxe jsou jedním z primárních prvků stromů syntaxe. Tyto uzly představují syntaktické konstrukce, jako jsou deklarace, příkazy, klauzule a výrazy. Každá kategorie uzlů syntaxe je reprezentována samostatnou třídou odvozenou od Microsoft.CodeAnalysis.SyntaxNode. Sada tříd uzlů není rozšiřitelná.
Všechny uzly syntaxe nejsou terminálové uzly ve stromu syntaxe, což znamená, že vždy mají jiné uzly a tokeny jako podřízené položky. Jako podřízený uzel jiného uzlu má každý uzel nadřazený uzel, ke kterému je možné přistupovat prostřednictvím SyntaxNode.Parent vlastnosti. Vzhledem k tomu, že uzly a stromy jsou neměnné, nadřazený uzel se nikdy nezmění. Kořen stromu má nadřazenou hodnotu null.
Každý uzel má metodu SyntaxNode.ChildNodes() , která vrací seznam podřízených uzlů v sekvenčním pořadí na základě jejich pozice ve zdrojovém textu. Tento seznam neobsahuje tokeny. Každý uzel má také metody pro zkoumání potomků, například DescendantNodes, DescendantTokensnebo DescendantTrivia – představující seznam všech uzlů, tokenů nebo trivií, které existují v podstromu kořenovém kořenem daného uzlu.
Kromě toho každá podtřída uzlu syntaxe zveřejňuje všechny stejné podřízené položky prostřednictvím vlastností silného typu. Třída uzlu má například BinaryExpressionSyntax tři další vlastnosti specifické pro binární operátory: Left, OperatorTokena Right. Typ Left a Right je ExpressionSyntaxa typ OperatorToken je SyntaxToken.
Některé uzly syntaxe mají volitelné podřízené položky. Například má IfStatementSyntax volitelnou položku ElseClauseSyntax. Pokud podřízená položka není přítomna, vrátí vlastnost hodnotu null.
Tokeny syntaxe jsou terminály gramatiky jazyka, které představují nejmenší syntaktické fragmenty kódu. Nikdy nejsou nadřazené jiným uzlům ani tokenům. Tokeny syntaxe se skládají z klíčových slov, identifikátorů, literálů a interpunkce.
Pro účely efektivity SyntaxToken je typ hodnoty CLR. Proto na rozdíl od uzlů syntaxe existuje pouze jedna struktura pro všechny druhy tokenů s kombinací vlastností, které mají význam v závislosti na typu tokenu, který je reprezentován.
Například celočíselný literál představuje číselnou hodnotu. Kromě nezpracovaného zdrojového textu, který token zahrnuje, má literál token Value vlastnost, která vám řekne přesnou dekódovanou celočíselnou hodnotu. Tato vlastnost je zadána, protože Object může být jedním z mnoha primitivních typů.
Vlastnost ValueText vám řekne stejné informace jako Value vlastnost, ale tato vlastnost je vždy zadána jako String. Identifikátor ve zdrojovém textu jazyka C# může obsahovat řídicí znaky Unicode, ale syntaxe samotné řídicí sekvence se nepovažuje za součást názvu identifikátoru. I když nezpracovaný text rozložený tokenem zahrnuje řídicí sekvenci, ValueText vlastnost ne. Místo toho obsahuje znaky Unicode identifikované řídicím znakem. Pokud například zdrojový text obsahuje identifikátor zapsaný jako \u03C0
, ValueText vrátí π
vlastnost tohoto tokenu .
Syntaxe trivia představuje části zdrojového textu, které jsou z velké části nevýznamné pro normální pochopení kódu, jako jsou prázdné znaky, komentáře a direktivy preprocesoru. Stejně jako tokeny syntaxe jsou trivia typy hodnot. Jeden Microsoft.CodeAnalysis.SyntaxTrivia typ se používá k popisu všech druhů trivií.
Vzhledem k tomu, že trivia není součástí normální syntaxe jazyka a může se objevit kdekoli mezi dvěma tokeny, nejsou zahrnuty do stromu syntaxe jako podřízený uzel. Vzhledem k tomu, že jsou důležité při implementaci funkce, jako je refaktoring a zachování úplné věrnosti se zdrojovým textem, existují jako součást stromu syntaxe.
Ke triviím můžete přistupovat kontrolou tokenů SyntaxToken.LeadingTrivia nebo SyntaxToken.TrailingTrivia kolekcí. Při analýze zdrojového textu jsou sekvence trivií přidružené k tokenům. Obecně platí, že token vlastní jakoukoli trivii za ním na stejném řádku až do dalšího tokenu. Jakákoli trivia za tímto řádkem je přidružena k následujícímu tokenu. První token ve zdrojovém souboru získá veškerou počáteční trivii a poslední posloupnost trivií v souboru se vysadí na token konce souboru, který má jinak nulovou šířku.
Na rozdíl od uzlů syntaxe a tokenů syntaxe nemají syntaxe nadřazené prvky. Vzhledem k tomu, že jsou součástí stromu a každý je přidružený k jednomu tokenu, můžete získat přístup k tokenu, který je přidružený k použití SyntaxTrivia.Token vlastnosti.
Každý uzel, token nebo trivia zná svou pozici ve zdrojovém textu a počet znaků, ze které se skládá. Pozice textu je reprezentována jako 32bitové celé číslo, což je index založený na char
nule. Objekt TextSpan je počáteční pozice a počet znaků, které jsou reprezentovány jako celá čísla. Pokud TextSpan má nulovou délku, odkazuje na umístění mezi dvěma znaky.
Každý uzel má dvě TextSpan vlastnosti: Span a FullSpan.
Vlastnost Span je rozsah textu od začátku prvního tokenu v podstromu uzlu na konec posledního tokenu. Toto rozpětí neobsahuje žádnou úvodní nebo koncovou trivii.
Vlastnost FullSpan je rozsah textu, který zahrnuje normální rozsah uzlu a rozsah všech úvodních nebo koncových trivií.
Příklad:
if (x > 3)
{
|| // this is bad
|throw new Exception("Not right.");| // better exception?||
}
Uzel příkazu uvnitř bloku má rozsah označený jedním svislým pruhem (|). Obsahuje znaky throw new Exception("Not right.");
. Celé rozpětí je označeno dvojitými svislými pruhy (||). Obsahuje stejné znaky jako rozpětí a znaky spojené s úvodní a koncovou trivií.
Každý uzel, token nebo trivia má SyntaxNode.RawKind vlastnost typu System.Int32, která identifikuje přesný prvek syntaxe reprezentovaný. Tuto hodnotu lze přetypovat do výčtu specifického jazyka. Každý jazyk, C# nebo Visual Basic, má jeden SyntaxKind
výčet (Microsoft.CodeAnalysis.CSharp.SyntaxKind a Microsoft.CodeAnalysis.VisualBasic.SyntaxKindv uvedeném pořadí), který obsahuje seznam všech možných uzlů, tokenů a trivií v gramatikě. Tento převod lze provést automaticky přístupem k CSharpExtensions.Kind metodám rozšíření nebo VisualBasicExtensions.Kind metodám rozšíření.
Tato RawKind vlastnost umožňuje snadnou nejednoznačnost typů uzlů syntaxe, které sdílejí stejnou třídu uzlů. U tokenů a trivií je tato vlastnost jediným způsobem, jak odlišit jeden typ prvku od jiného.
Například jedna BinaryExpressionSyntax třída má Left, OperatorTokena Right jako děti. Vlastnost Kind rozlišuje, zda se jedná o AddExpressionuzel , SubtractExpressionnebo MultiplyExpression druh syntaxe.
Tip
Doporučujeme zkontrolovat typy použití IsKind (pro jazyk C#) nebo IsKind (pro metody rozšíření VB).
I když zdrojový text obsahuje chyby syntaxe, zobrazí se úplný strom syntaxe, který je do zdroje zaokrouhlený. Když analyzátor narazí na kód, který neodpovídá definované syntaxi jazyka, použije k vytvoření stromu syntaxe jednu ze dvou technik:
Pokud analyzátor očekává určitý druh tokenu, ale nenajde ho, může do stromu syntaxe vložit chybějící token do požadovaného umístění tokenu. Chybějící token představuje skutečný token, který byl očekáváno, ale má prázdné rozpětí a jeho SyntaxNode.IsMissing vlastnost vrátí true
.
Analyzátor může tokeny přeskočit, dokud nenajde, kde může pokračovat v analýze. V tomto případě jsou přeskočené tokeny připojeny jako trivia uzel s druhem SkippedTokensTrivia.
Zpětná vazba k produktu .NET
.NET je open source projekt. Vyberte odkaz pro poskytnutí zpětné vazby:
Události
Vytváření inteligentních aplikací
17. 3. 23 - 21. 3. 23
Připojte se k řadě meetupů a vytvořte škálovatelná řešení AI založená na skutečných případech použití s kolegy vývojáři a odborníky.
Zaregistrovat