19. januar 2008 - 16:56Der er
35 kommentarer og 1 løsning
Elisp og regex
Hej
Jeg er ved at lave en form for bibliotek til STL i elisp til emacs. Her bruger jeg regexp til at finde tekst af typen: object.member(); object.member; object->member(); object->member;
Jeg har makket en regexp sammen: \s*([a-z]+)(->|\.)([a-z]+)((\([a-z,\"]+\);)|(\(\);)|;)\s* Jeg ved udemærket godt at den måske kunne være bedre. Jeg er nybegynder indenfor regexp, men jeg har testen denne regexp via http://www.fileformat.info/tool/regex.htm og den fortæller mig at den virker, så det er jeg tilfreds med. Nu vil jeg gerne have den oversat så jeg kan bruge den i emacs, men jeg bliver forvirret af syntaksen. Jeg har fundet følgende side http://www.gnu.org/software/emacs/elisp-manual/html_mono/elisp.html#Syntax-of-Regexps som jeg bruger til at oversætte. Jeg er nået frem til noget, som ikke virker, og jeg er overbevist om at det er mig der ikke kan finde ud af at lave en elisp regexp. Her er hvad jeg er kommet op med: [[:blank:]]*([[:alpha:]]+)\(->\|\s.\)([[:alpha:]]+)(\(\s([[:alpha:],\"]+\s);\)\|\(\s(\s);\)\|;\)[[:blank:]]* Det jeg roder mest rundt i er escape karakteren. \ og dens virkemåde i nogen sammenhæng. En eller anden der kan hjælpe mig? Er nemlig meget tæt på at være i mål med denne extension til emacs.
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
Helt så oldnordisk ser syntaksen nu ikke ud til at være.
Jeg tror at det største problem er at '(', ')', '|' og '\' hver i sær skal escapes fordi at det foregår i en LISP kontekst. Dit originale møsnter burde blive noget i stil med:
Så vidt jeg kan se er det kun \s som den ikke forstår.
Det med at visse tegn skal escapes når de indgår i en streng er et problem i mange andre sprog. Lige her er det vist mere LISP du skal være irriteret på. :^)
emacs er lisp :) Er irriteret på det hele. Nu kan jeg godt kalde regexp'en med en interaktiv funktion, men når jeg prøver at lave min egen funktion med regexp'en, så fejler den.
Emacs er ikke LISP - den er måske lavet i LISP, men LISP er nu et helt programmeringssprog i egen ret og har specielt anvendelse inden for AI (Ateficial Intelligence).
Som programmerinssprog har LISP nogle krav til sin syntaks. Og da f.eks. '(' og ')' indgår temmeligt cebtralt i syntaksen skal de escapes i tekststrenge.
Ja okay :) Bare en talemåde jeg har fået påført mig. Ved godt at det ikke er sandt. Synes bare at det er grimt med alle de \\\. Altså hvis jeg bare vil vise en (, så skal den escapes med tre \?
Hvis '(' skal matche en parantes - i modsætning til f.eks. at indgå i en gruppe - så kræver regexp at den skal escapes:
\(
LIST kræver selv at både '\' og '(' skal escapes:
\\\(
Det kunne dog blive værre. F.eks. hvsi det var et '\' der skal matches. Den bliver til:
\\\\
Det er rigtigt "dejligt" når både regexp og programerinsgsprog begge to kræver escaping - det kan blive til nogle temmeligt ulæselige udtryk. Det ville dog være forkert at sige at det var noget unikt for LISP...
Ja. Når jeg prøver at evaluere denne funktion: (defun lookup () "Funktionen finder strenge af typerne, object.member();, object->member() osv." (interactive) (re-search-backward "[:blank:]*\([a-z]+\)\(->\|\\.\)\([a-z]+\)\(\(\\\([a-z,\\"]+\\\);\)\|\(\\\(\\\);\)\|;\)[:blank:]*") )
Får jeg følgende fejl: Debugger entered--Lisp error: (invalid-read-syntax "]" in al list")
Men kalder jeg re-search-backward interaktivt med M-x, så kan den godt evaluere regexp'en. Det ser ud til at den godt kan klare object->member; men alt andet fejler den ved. Altså, object->member("string",arg,); object.member("string",arg,); object.member(); object.member; object->member()
Ser ud til at alle \ skal escapes igen. For at evaluere funktionen skal de escapes igen, så den kommer til at se sådan her ud, "[:blank:]*\\([a-z]+\\)\\(->\\|\\\\.\\)\\([a-z]+\\)\\(\\(\\\\\\([a-z,\\\\\"]+\\\\\\);\\)\\|\\(\\\\\\(\\\\\\);\\)\\|;\\)[:blank:]*
Den kan dog stadig ikke finde tekst af følgende form: object->member("string",arg,); object.member("string",arg,); object.member(); object.member; object->member() Den kan kun finde: object.member;
Det jeg skal bruge regexp'en til er at skaffe object og member. Det der er mellem () er jeg ligeglad med. Det kan være gyldig eller ugyldig C++ kode. Jeg skal bruge object til at finde typen af object og derefter skal jeg bruge member til at finde en fil på ala ~/stl-reference/type-member. hvor type er typen på objektet. Er ved at lave en lille STL reference :) Som skal kunne virke ved at trykke på en F tast.
Måske bare mig der er ringe til at sætte formen op :) min regexp skal kunne fx kunne finde
vector v; v.assign("hej");
Her skal den kunne finde v og assign. Derefter laver jeg en ny regexp som via v finder vector, og derfter åbner filen "vector-assign", som så indholder info omkring assign.
Din version er næsten rigtig, i følge fileformat.info/tool/regex.htm :) Men elisps re-search-backward kan stadig kun finde object->member; Kan se du bruger (?:) er det anonyme klasser? Eller hvad det nu hedder. Det er smart!!
re-search-backward vil jeg ikke normalt anbefale at man bruger - regexp'er er nu engang beregnet til at blive brugt fra venstre til højre.
Forsøg at udvide motoren til også at kunne matche højre til venstre har ikke ubetinget succesfulde. Og jeg tør i hvert fald ikke gætte på hvad der egentlig sker internt i regexp-motoren i netop dette her tilfælde.
Jeg har en fil med som ser sådan her ud: object->member(string,arg, ...); object.member(string,arg, ...); object.member(); object.member; object->member(); object->member; object->member;
Når jeg afprøver regex'en, evaluere jeg min loopup funktion og kalder funktionen via M-x lookup [RET]. Derefter finder den kun object->member;. Ikke nogen af de andre.
Synes jeg også. Har lige forhørt mig på emacs kanalen på irc.freenod.org. De har givet mig en anden tilgang. En macro der hedder rx, skulle vist være en anden måde at opfatte regexps på i LISP (sikkert lavet fordi det er usansynlig svært at overskue denne ødelagte syntaks :P). rx, har en lisp orienteret tilgang til at lave regexps på. Emacs har desuden en re-builder også, som jeg også lige vil kigge på. Jeg skal lige spise, og vender defter tilbage til regexp'et. Jeg giver lige besked fra mig når jeg har afprøvet rx.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.