Megosztás a következőn keresztül:


Szintaxis használata

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.

Feljegyzé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 hibásan formázott a kihagyott vagy hiányzó jogkivonatok ábrázolásával.
  • 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. A fa beszerzése után pillanatképet ad a kód aktuális állapotáról, és 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, ami azt jelenti, hogy gyermekként mindig más csomópontokkal és jogkivonatokkal rendelkeznek. 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 jogkivonatokat. 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 típus Left és az isExpressionSyntax, és a típus OperatorToken az SyntaxTokenRight .

Egyes szintaxiscsomópontok nem kötelező gyermekekkel rendelkeznek. Például egy IfStatementSyntax nem kötelező ElseClauseSyntax. Ha a gyermek nincs jelen, a tulajdonság null értéket ad vissza.

Szintaxis jogkivonatai

A szintaxis jogkivonatai a nyelvhelyesség termináljai, amelyek a kód legkisebb szintaktikai töredékeit jelölik. Soha nem más csomópontok vagy jogkivonatok szülei. A szintaxis jogkivonatai 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 szintaxiscsomópontoktól eltérően minden típusú jogkivonathoz csak egy struktúra tartozik, amely a megjelenített token típusától függően jelentéssel rendelkező tulajdonságok kombinációjával rendelkezik.

Egy egész számkonstans jogkivonat például egy numerikus értéket jelöl. A jogkivonat nyers forrásszövege mellett a literális jogkivonatnak van egy Value tulajdonsága, amely a pontos dekódolt egész szám értékét jelzi. 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 jogkivonat által átfoglalt nyers szöveg tartalmazza a feloldósorozatot, a ValueText tulajdonság nem. Ehelyett a feloldó által azonosított Unicode-karaktereket tartalmazza. Ha például a forrásszöveg olyan azonosítót tartalmaz, amely a következőként \u03C0van megírva, akkor a jogkivonat tulajdonsága ValueText lesz visszaadva π.

Szintaxis trivia

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 szintaxis jogkivonataihoz hasonlóan a trivia is értéktípusok. 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 jogkivonat között bárhol megjelenhet, a csomópont gyermekként nem szerepel a szintaxisfában. 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 jogkivonatok SyntaxToken.LeadingTrivia vagy SyntaxToken.TrailingTrivia gyűjtemények vizsgálatával hozzáférhet a trivia-hoz. A forrásszöveg elemzésekor a rendszer a mellékjelek sorozatait társítja a jogkivonatokhoz. Általánosságban elmondható, hogy a jogkivonatok a következő jogkivonatig ugyanazon a sorban lévő összes triviát birtokolják. A sor utáni esetleges trivia az alábbi jogkivonattal van társítva. A forrásfájl első tokenje lekéri az összes kezdeti triviát, és a fájl utolsó trivia-sorozata a fájlvégi jogkivonatra kerül, amely egyébként nulla szélességű.

A szintaxiscsomópontoktól és a jogkivonatoktól eltérően a szintaxis-trivia nem rendelkezik szülőkkel. Mivel ezek a fa részei, és mindegyik egyetlen jogkivonathoz van társítva, hozzáférhet a tulajdonság használatával SyntaxTrivia.Token társított jogkivonathoz.

Ível

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.

A Span tulajdonság a csomópont alterületének első tokenjének kezdetétől az utolsó jogkivonat 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élda:

      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. Tartalmazza a karaktereket throw new Exception("Not right.");. A teljes tartományt a két függőleges sáv (||) jelzi. Ugyanazokat a karaktereket tartalmazza, mint a span, valamint a kezdő és a záró triviához társított karaktereket.

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) egyetlen SyntaxKind enumerálási (Microsoft.CodeAnalysis.CSharp.SyntaxKind és Microsoft.CodeAnalysis.VisualBasic.SyntaxKind, illetve) felsorolása van, amely felsorolja a nyelvhelyesség összes lehetséges csomópontját, jogkivonatát és trivia-elemét. Ez az átalakítás automatikusan elvégezhető a bővítmények vagy VisualBasicExtensions.Kind a bővítmények metódusainak CSharpExtensions.Kind 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. A jogkivonatok és a trivia esetében ez a tulajdonság az egyetlen módja annak, hogy megkülönböztesse az egyik elemtípust a másiktól.

Egy osztály például BinaryExpressionSyntax rendelkezik Left, OperatorTokenés Right gyermekként is. A Kind tulajdonság megkülönbözteti, hogy egy , SubtractExpressionvagy MultiplyExpression egy szintaktikai csomópontról van-e AddExpressionszó.

Tipp.

Javasoljuk, hogy a (C#) vagy IsKind a (VB) kiterjesztésű metódusok használatával IsKind ellenőrizze a típusokat.

Errors

Még akkor is, ha a forrásszöveg szintaxishibákat tartalmaz, egy teljes szintaxisfa jelenik meg, amely a forráshoz ciklikusan háromszorozható. 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ó jogkivonat a várt tényleges jogkivonatot jelöli, de üres tartományt tartalmaz, és a tulajdonsága SyntaxNode.IsMissing visszaadja true.

  • Az elemző kihagyhatja a jogkivonatokat, amíg meg nem találja azt, ahol folytathatja az elemzést. Ebben az esetben a kihagyott jogkivonatok trivia csomópontként vannak csatolva, ilyen típusúak SkippedTokensTrivia.