You are here
Home > articles

Ilya Sivkov.

Signal-Slot-diagram ved hjelp av Doxygen og XSLT.

Noen ganger ma jeg se sammenhenger mellom signaler og spor i mine Qt-prosjekter. Det virker som na er det ingen programvare enn det kan gjore dette. Mange programmer kan tegne kallegrafer, men ingen av dem fungerer med Qt-signaler.

Jeg bestemte meg for a skrive egen C ++-parser, men snart hadde jeg sluppet ut at det er en sv rt komplisert oppgave. Det vil ta mye tid uten noe passende resultat.

Sa, jeg trenger noe som kan analysere C ++-filer for meg. Og jeg fant ut at Doxygen kan gjore det. Den produserer XML-filer med beskrivelse av klassestruktur og kodeoppforing, som er enkle a analysere.

La oss starte med et par klasser for a utforske Doxygen-utgangen:

SenderClass gjor ingenting unntatt a sende mySignal_01 signal. Den eneste virkningen av RecieverClass er tilkobling til dette signalet:

Na kan vi behandle det med neste Doxygen-fil:

Dette vil opprette XML-katalog med noen XML-filer. Tre av dem er knyttet til avsenderklassen:

ClassSender.xml-filen inneholder informasjon om Sender klassestruktur.

Den innbefatter «compounddef & # 062; element med flere & # 060; sectiondef & # 062; barn for ulike medlemmer og tilgangstyper:

Hver & # 060; sectiondef & # 062; inkluderer & # 060; medlemdef & # 062; elementer med det slags (funksjon, variabel, signal eller spor), type, argumenter og plassering, dvs. fil og linjer der den er plassert.

En annen nyttig fil er sender_8cpp.xml. Dette er et programoppforing med hoydepunktsalternativer for sokeord, strenger, etc. Vi bruker den til a soke QObject :: connect () samtaler for videre parsing.

For du fortsetter, vil det v re nyttig a kombinere alle XML-filer generert av Doxygen, til stor en. Den neste kommandoen gjor det:

saxonb-xslt-s index.xml -xsl: combine.xsl.

For a fa tilkoblingsdata ma vi gjore folgende:

& # 8211; finn QObject :: connect () samtaler.

& # 8211; dele det i argumenter.

& # 8211; skaffe typer avsender- og mottakerklasse-, signal- og spormedlemmer.

& # 8211; bygge tilkoblingsliste.

& # 8211; sla sammen det med original all.xml-filen.

Som et resultat vil hver & # 060; medlemdef & # 062; med @kind tilsvarer «signal» eller «spor» bor man fa nye elementer som viser hvilke signaler eller spor det er koblet til. Da kan vi enkelt bruke det til tegningstegning, ubrukte medlemssok etc.

Tilkoblingsstrengsok.

Na ma vi finne kode linjer med tilkoblingskommandoer. Det er enkelt, fordi disse linjene alltid starter med tilkobling (kanskje med mellomrom.

Sa kan kampfunksjonen brukes med regexp’ ^ \ s * connect \ s * \ (‘. Husk at all kode er inneholdt i kodelinjeelementer splittet i hoydepunkt for forskjellige bokstavtyper (sokeord, tall, etc.). streng er en enkel tekst, sa den er inneholdt i et enkelt hoydepunktselement. Sa, den endelige XPath-sporringen vil v re.

Men kodelinjen som ble funnet med denne sporringen, kan ikke inneholde hele tilkoblingskommandoen, fordi den ofte er brutt i flere linjer. Heldigvis forbinder samtalen alltid med semikolon, sa det er nok a samle alle kodelinjer til semikolon er funnet.

Det er gjort med kode nedenfor:

Her bruker vi findsemicolon modus, fordi andrewice den andre og den tredje malen vil samsvare med alle strengene med semikolon.

Parsing av tilkoblingsstreng.

A ha hele tilkoblingssamtalen, er neste trinn a trekke ut fire deler av denne anropet:

Den siste delen kan v re signal fordi Qt tillater ikke bare signal til spor-tilkobling, men signal til signal ogsa.

XSLT 2.0 introduserer sv rt nyttig «xsl: analyser-streng & # 062; element. Det tillater oss a analysere strengen, fange den og deretter opprette resultat ved hjelp av regex-gruppefunksjonen.

Her er en funksjon som godtar tilkoblingsstrengen og returnerer den. Det sier ogsa er tilkoblingsmalsignalet eller -sporet.

Sender og mottaker parsing.

Nar avsender, mottaker, signal og maldeler er hentet, kan vi analysere dem separat. La oss begynne med avsender og mottaker. Begge kan bare v re klassefelter, eller metallsamtaler, eller ringer av feltets metode, osv., Eller bare denne pekeren. For eksempel:

Som du ser, er det vanligste tilfellet felt / metodekjede med seksjoner atskilt med prikk ‘.’ eller minus-storre par ‘- & amp; gt;’ . Det kan v re tokenized via neste regul re uttrykk:

Den trekker ut den forste kjeden delen, det er parentes (det er det), seksjonsseparator og resten av strengen. Ved hjelp av denne regexp kan vi skrive funksjon som deler var anropskjede i seksjoner:

Etter den forste delenekstraksjonen, kontrollerer den om det er en separator etter det, og hvis det er, sprer rekursivt resten av inngangen. Som et resultat returnerer den sekvensen av & # 060; token & # 062; elementer som inneholder navnet pa medlemmet som heter og det er type & # 8212; felt eller funksjon (ikke forveksle med type i C ++-betydning og vi finner det nedenfor).

Gjeldende klassesok.

For a finne en klasse som den nav rende koden tilhorer, ma vi forst finne en metode som inneholder gjeldende kode linje. V r oppmerksom pa at kodeoppforing og klassedeklarasjon tilhorer forskjellige «# 060; compounddef & # 062; elementer av sammensatt XML-fil. De kan knyttes via & # 060; medlemdef & # 062; s element & # 060; plassering & # 062; Den har tre attributter:

bodyfile & # 8211; den fullstendige banen til filen inneholder metodedeklarasjon, bodystart & # 8211; den forste linjen i metodekroppen, bodyend & # 8211; den siste.

Forst lar vi ta en fil som den nav rende kodelinjen tilhorer:

Deretter kan vi finne en metode hvis definisjon er i denne filen, og som starter for den nav rende kodelinjen og slutter etter den:

Na kan vi finne en klasse:

Avsender og mottaker type deteksjon.

A ha en nav rende klasse og avsender / mottaker splittet i individuelle samtaler, vi kan na finne klassen i den siste delen av kjeden. For a gjore det finner vi medlemmet et navn og et slag (funtion eller variabel) som er angitt av den forste delen av anropskjeden, og deretter far du den (for en funksjon blir det returtype). Denne typen (som er garantert a v re en klasse) kan brukes til a behandle neste del av anropskjeden.

Lar skrive en funksjon for det:

Forst tar du det forste token i en kjede:

Deretter velger du en slags klassemedlem vi skal soke.

Det vil bli brukt til snill attributt.

Deretter kan vi finne en klasse. Hvis symbolet & # 8217; s & # 060; navn & # 062; elementet er «dette», da onsket klasse er den nav rende metodeklassen selv. Otherwice, denne klassen kan bli funnet ved refid attributten av & # 060; ref & # 062; element inni & # 060; type & # 062; av klassemedlem med navn lik kjedeavsnittets navn:

Her far vi klassen ID, ikke selve klassen. Den er ferdig fordi «xsl: sekvens & # 062; inne i en variabel vil opprette en kopi av noden, sa vi mister en nodes overordnet.

Na fa klassen definisjonen selv:

Hvis token vi behandler er den siste i kjeden, returner den. Ellers kalles rekursivt funksjon med den funnet klassen som eier for neste token:

Signal og spor type deteksjon.

Na kan vi se signal- og spor-signaturene. Vi har allerede oppnadd det nar vi analyserer hele tilkoblingslinjen. Vi har & # 060; signal & # 062; element med signatur signatur og & # 060; mal & # 062; element med dets underskrift og type (er det et signal eller et spor).

Sett inn et variabelt mal for a behandle bade navn / type par og et enkelt navn pa samme mate:

Del opp malstrengen i to deler: Navn og argumenter:

Finn na et medlem med dette navnet og typen:

Slett forbindelsesinformasjon.

Ga na tilbake til hoveddelen av var XSLT. Vi har allerede fatt all informasjon om tilkobling.

Finn kode linje, metode og klasse, som vi gjorde over:

Split-tilkobling () samtale:

Hent avsenderklasse:

Fa et signalmedlem:

Gjor det samme for mottaker og mal.

Slett tilkoblingsdata.

saxonb-xslt -s: all.xml -xsl: conn.xsl -o: conns.xsl.

Sla sammen tilkoblingsdata med originalfil.

Etter sammenkoblingslistegenerering lar vi sammenfoye disse dataene med den originale komponerte XML-filen.

Les forst forbindelsesdata til variabelen:

Definer na identitetstransformasjon for hele dokumentet.

For spormedlemmer, legg til mottaker fra koder med ID for signal som dette sporet mottar:

Signaler kan bade sende seg og motta andre signaler, sa legg til mottak fra og send til koder for det:

For a legge til signaler som nav rende mal mottar, finn alle tilkoblinger med mottaker tilsvarer gjeldende medlems-ID:

Pa samme mate legger du til mal det nav rende signalet sender til:

Top

Vil du spille i det mest heldige kasinoet? Vi samlet det for deg. Spill her nå!