Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A szintaxisfa a fordító API-k által közzétett alapvető nem módosítható adatszerkezet. Ezek a fák a forráskód lexikális és szintaktikai szerkezetét képviselik. Két fontos célt szolgálnak:
- Ahhoz, hogy az eszközök – például az IDE, a bővítmények, a kódelemzési eszközök és az újrabontások – lehetővé tegyék a forráskód szintaktikai szerkezetének megtekintését és feldolgozását a felhasználó projektjében.
- Ha lehetővé szeretné tenni, hogy az eszközök – például az újrabontások és az IDE – természetes módon, közvetlen szövegszerkesztés nélkül hozzanak létre, módosíthassanak és átrendezhessenek forráskódot. A fák létrehozásával és módosításával az eszközök könnyen létrehozhatják és átrendezhetik a forráskódot.
Szintaxisfák
A szintaxisfák a fordításhoz, a kódelemzéshez, a kötéshez, az újrabontáshoz, az IDE-funkciókhoz és a kódgeneráláshoz használt elsődleges struktúra. A forráskód egyetlen részét sem értelmezi a rendszer anélkül, hogy először azonosítanák és kategorizálják a számos jól ismert szerkezeti nyelvi elem egyikébe.
Megjegyzés:
A RoslynQuoter egy nyílt forráskódú eszköz, amely a program szintaxisfája létrehozásához használt szintaxis-előállító API-hívásokat mutatja be. Ha élőben szeretné kipróbálni, tekintse meg http://roslynquoter.azurewebsites.net.
A szintaxisfák három fő attribútummal rendelkeznek:
- Minden forrásinformációt teljes hűségben tárolnak. A teljes hűség azt jelenti, hogy a szintaxisfa tartalmazza a forrásszövegben található összes információt, minden nyelvtani szerkezetet, minden lexikális jogkivonatot és minden mást a kettő között, beleértve a szóközt, a megjegyzéseket és az előfeldolgozási irányelveket. A forrásban említett összes literál például pontosan úgy jelenik meg, ahogy beírta. A szintaxisfák akkor is rögzítik a forráskód hibáit, ha a program hiányos vagy helytelenül formázott azáltal, hogy ábrázolják a kihagyott vagy hiányzó tokeneket.
- Pontosan azt a szöveget tudják előállítani, amelyből elemezték őket. Bármely szintaxiscsomópontból lekérhető az adott csomóponton gyökerező részhalmaz szöveges ábrázolása. Ez a képesség azt jelenti, hogy a szintaxisfákat használhatja a forrásszövegek létrehozásához és szerkesztéséhez. Ha létrehoz egy fát, azzal egyenértékű szöveget hoz létre, és ha egy meglévő fa módosításaiból új fát hoz létre, akkor hatékonyan szerkesztette a szöveget.
- Nem módosíthatók és szálbiztosak. Miután a fát megszerezték, pillanatkép készül a kód aktuális állapotáról, és ez soha nem változik. Ez lehetővé teszi, hogy több felhasználó egyszerre használja ugyanazt a szintaxisfát különböző szálakban zárolás vagy duplikáció nélkül. Mivel a fák megváltoztathatatlanok, és nem módosíthatók közvetlenül egy fán, a gyári metódusok további pillanatképek létrehozásával segítenek létrehozni és módosítani a szintaxisfákat. A fák hatékonyan használják fel a mögöttes csomópontokat, így az új verzió gyorsan és kevés extra memóriával újraépíthető.
A szintaxisfa szó szerint egy fa adatszerkezete, ahol a nem terminális szerkezeti elemek más elemeket is fölérendelnek. Minden szintaxisfa csomópontokból, jogkivonatokból és triviákból áll.
Szintaxiscsomópontok
A szintaxiscsomópontok a szintaxisfák egyik elsődleges elemei. Ezek a csomópontok olyan szintaktikai szerkezeteket képviselnek, mint a deklarációk, utasítások, záradékok és kifejezések. A szintaxiscsomópontok kategóriáit egy külön osztály Microsoft.CodeAnalysis.SyntaxNodejelöli. A csomópontosztályok halmaza nem bővíthető.
Minden szintaxiscsomópont nem terminálcsomópont a szintaxisfán, amelyek mindig más csomópontokkal és tokenekkel rendelkeznek gyermekként. Egy másik csomópont gyermekeként minden csomóponthoz tartozik egy szülőcsomópont, amely a SyntaxNode.Parent tulajdonságon keresztül érhető el. Mivel a csomópontok és a fák nem módosíthatók, a csomópont szülője soha nem változik. A fa gyökere null szülővel rendelkezik.
Minden csomópont rendelkezik egy SyntaxNode.ChildNodes() metódussal, amely szekvenciális sorrendben adja vissza a gyermekcsomópontok listáját a forrásszövegben elfoglalt helyük alapján. Ez a lista nem tartalmaz tokeneket. Minden csomópont rendelkezik olyan módszerekkel is, amelyekkel megvizsgálhatja a leszármazottakat, például DescendantNodes, DescendantTokensvagy DescendantTrivia - amelyek az adott csomópont által gyökerező alhálózatban található összes csomópont, jogkivonat vagy trivia listáját jelölik.
Emellett minden szintaxiscsomópont-alosztály szigorúan beírt tulajdonságokon keresztül teszi elérhetővé ugyanazokat a gyermekeket. Egy csomópontosztály például BinaryExpressionSyntax három további, a bináris operátorokra jellemző tulajdonsággal rendelkezik: Left, OperatorTokenés Right. A Left és a Right típusa ExpressionSyntax, és a OperatorToken típusa SyntaxToken.
Egyes szintaxiscsomópontok választható gyermekekkel rendelkeznek. Például egy IfStatementSyntax opcionális ElseClauseSyntax. Ha a gyermek nincs jelen, a tulajdonság null értéket ad vissza.
Szintaxis elemei
A szintaxis tokenjei a nyelvtan termináljai, amelyek a kód legkisebb szintaktikai töredékeit jelölik. Soha nem szülők más csomópontok vagy tokenek számára. A szintaxis elemei kulcsszavakból, azonosítókból, literálokból és írásjelekből állnak.
A hatékonyság érdekében a SyntaxToken típus egy CLR-értéktípus. Ezért, a szintaxis csomópontoktól eltérően, minden tokenfajtához csak egy struktúra tartozik, amely az adott tokenfajta által hordozott jelentésű tulajdonságok keverékével rendelkezik.
Például egy egész számkonstans jel számszerű értéket képvisel. A nyers forrásszöveg mellett a literális token egy Value tulajdonsággal rendelkezik, amely megadja a pontos dekódolt egész szám értékét. Ez a tulajdonság azért van begépelve Object , mert a sok primitív típus egyike lehet.
A ValueText tulajdonság ugyanazokat az információkat adja meg, mint a Value tulajdonság, de ez a tulajdonság mindig a következőképpen van begépelve String. A C#-forrásszövegben szereplő azonosítók tartalmazhatnak Unicode-feloldó karaktereket, de maga a feloldósorozat szintaxisa nem számít az azonosító nevének. Tehát bár a token által felölelt nyers szöveg tartalmazza az escape szekvenciát, a ValueText tulajdonság nem. Ehelyett az escape által azonosított Unicode-karaktereket tartalmazza. Ha például a forrásszöveg azonosítót tartalmaz, amely \u03C0
formában van megírva, akkor az ennek megfelelő ValueText tulajdonság visszaadja a π
értéket.
Szintaxis érdekességek
A szintaxis trivia a forrásszöveg azon részeit jelöli, amelyek nagyrészt jelentéktelenek a kód normál megértéséhez, például a szóköz, a megjegyzések és az előfeldolgozási irányelvek. A szintaktikai elemekhez hasonlóan a trivia is értéktípus. Az egyetlen Microsoft.CodeAnalysis.SyntaxTrivia típus a különféle triviák leírására szolgál.
Mivel a trivia nem része a normál nyelv szintaxisának, és bármelyik két távoli egység között bárhol megjelenhet, nem szerepelnek a szintaxisfában, mint a csomópontok gyermekei. Mivel azonban fontosak egy olyan funkció implementálásakor, mint az újrabontás és a forrásszöveg teljes hűségének fenntartása, ezek a szintaxisfa részeként léteznek.
A tokenek SyntaxToken.LeadingTrivia vagy SyntaxToken.TrailingTrivia gyűjteményeinek vizsgálatával hozzáférhet a triviahoz. Amikor a forrásszöveget elemezzük, a rendszer trivia sorozatokat társít a jelölőkhöz. Általánosságban elmondható, hogy egy token birtokolja ugyanazon a soron az utána következő összes kommentárt egészen a következő tokenig. A sor utáni esetleges trivia az alábbi szókivonattal van társítva. A forrásfájl első tokenje megkapja az összes kezdeti érdektelen információt, és a fájl utolsó érdektelen információ sorozata a fájlvégi tokenhez kerül, amely egyébként nincs szélessége.
A szintaxiscsomópontoktól és a tokenektől eltérően a szintaxis apróságok nem rendelkeznek szülőkkel. Mivel ezek a fa részei, és mindegyik egyetlen tokenhez van társítva, hozzáférhet a hozzá társított tokenhez a SyntaxTrivia.Token tulajdonság használatával.
Tartományok
Minden csomópont, jogkivonat vagy trivia ismeri a forrásszövegben elfoglalt helyét és a benne lévő karakterek számát. A szöveges pozíció 32 bites egész számként jelenik meg, amely nulla alapú char
index. Az TextSpan objektum az első pozíció és a karakterek száma, mindkettő egész számként jelenik meg. Ha TextSpan nulla hosszúságú, akkor két karakter közötti helyre utal.
Minden csomópontnak két TextSpan tulajdonsága van: Span és FullSpan.
Az Span tulajdonság a csomópont aldendrogramjának első tokenjétől az utolsó token végéig terjedő szövegtartomány. Ez az időtartam nem tartalmaz semmilyen kezdő vagy záró triviát.
A FullSpan tulajdonság az a szövegtartomány, amely tartalmazza a csomópont normál tartományát, valamint az esetleges kezdő vagy záró triviák szélességét.
Például:
if (x > 3)
{
|| // this is bad
|throw new Exception("Not right.");| // better exception?||
}
A blokkon belüli utasításcsomópontnak az egyetlen függőleges sáv (|) által jelzett spanja van. Ez tartalmazza a karaktereket throw new Exception("Not right.");
. A teljes tartományt a két függőleges sáv (||) jelzi. A span karaktereit, valamint a kezdő és záró triviahoz kapcsolódó karaktereket tartalmazza.
Típusok
Minden csomópont, jogkivonat vagy trivia rendelkezik egy SyntaxNode.RawKind olyan típusú System.Int32tulajdonságtal, amely azonosítja a pontos szintaktikai elemet. Ez az érték egy nyelvspecifikus számbavételre vethető. Minden nyelvnek (C# vagy Visual Basic) van egyetlen SyntaxKind
enumerációja (Microsoft.CodeAnalysis.CSharp.SyntaxKind és Microsoft.CodeAnalysis.VisualBasic.SyntaxKind, illetve), amely felsorolja a nyelvtani szabályok összes lehetséges csomópontját, tokenjét és trivia elemét. Ez az átalakítás automatikusan elvégezhető a CSharpExtensions.Kind vagy a VisualBasicExtensions.Kind bővítmény-metódusok elérésével.
A RawKind tulajdonság lehetővé teszi az azonos csomópontosztályt használó szintaxiscsomópontok egyszerű egyértelműsítését. Tokenek és trivia esetében ez a tulajdonság az egyetlen mód az elemtípusok megkülönböztetésére.
Például, egyetlen BinaryExpressionSyntax osztálynak Left, OperatorToken, és Right a gyermekei vannak. A Kind tulajdonság megkülönbözteti, hogy ez egy AddExpression, SubtractExpression vagy MultiplyExpression típusú szintaktikai csomópont.
Jótanács
Javasolt IsKind (C#-hez) vagy IsKind (VB-hez) kiterjesztésű metódusok használatával ellenőrizni a típusokat.
Hibák
Még akkor is, ha a forrásszöveg szintaxishibákat tartalmaz, egy teljes szintaxisfa kerül bemutatásra, amely visszaállítható a forrásra. Amikor az elemző olyan kóddal találkozik, amely nem felel meg a nyelv meghatározott szintaxisának, két módszer egyikével hoz létre szintaxisfát:
Ha az elemző egy adott típusú jogkivonatot vár, de nem találja, előfordulhat, hogy beszúr egy hiányzó jogkivonatot a szintaxisfába azon a helyen, ahol a jogkivonatot várta. A hiányzó token az a tényleges token, amelyet vártak, de üres tartományú, és a SyntaxNode.IsMissing tulajdonsága
true
értéket ad vissza.Az elemző kihagyhatja a tokeneket, amíg meg nem találja azt, ahol folytatható az elemzés. Ebben az esetben a kihagyott tokenek trivia-csomópontként vannak csatolva, mint a következő típus: SkippedTokensTrivia.