help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: how to use parsing expressing grammar


From: Helmut Eller
Subject: Re: how to use parsing expressing grammar
Date: Sun, 21 Dec 2008 12:24:41 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux)

* Xah Lee [2008-12-20 23:27+0100] writes:

> Hi Helmut,
>
> another question i have is, how do i capture text as in regex's “\(...
> \)”, “\1”?
>
> I know in your elisp header file it mentions
>
> ;;  (action FORM)          ; evaluate FORM
> ;;  `(VAR... -- FORM...)   ; stack action
>
> how do i capture match using that?

Basically there are 2 phases.  The first phase parses, i.e., decides
which rules match, and the second phase executes actions.  Actions are
executed at the point of match.  The action can do whatever is needed.

The peg stack can be use to pass values between actions.  You don't have
to use the stack, you could also use global variables or whatever is
convenient.

[...]
> suppose i want to swap the src and alt text and have
>
> <img src="pretty" alt="some.png" width="33" height="33" >

That's a bit complicated, but I think it's also a bit complicated to swap
to submatches with regexps.  Let's assume that we have a helper function
to swap two regions:

(defun swap-regions (start1 end1 start2 end2)
  (if (< start2 start1) 
      (swap-regions start2 end2 start1 end1)
    (let ((string1 (buffer-substring start1 end1))
          (string2 (buffer-substring start2 end2)))
      (delete-region start2 end2)
      (goto-char start2)
      (insert string1)
      (delete-region start1 end1)
      (goto-char start1)
      (insert string2))))

Then this should work:

(defun doMyReplace ()
  (interactive)
  (let (src-start src-end alt-start alt-end)
    (peg-parse
     (imgTag "<img" _ (+ attributes _) ">")
     (attributes (or src alt width height))
     (src "src" = 
          (action (setq src-start (point)))
          "\"" filePath "\""
          (action (setq src-end (point))))
     (filePath (+ [A-Z a-z "./_-"]))
     (alt "alt" = 
          (action (setq alt-start (point)))
          "\"" altStr "\"" 
          (action (setq alt-end (point))))
     (altStr (* [A-Z a-z "./ '_"]))
     (width "width" =  "\"" digits "\"")
     (height "height" = "\"" digits "\"")
     (= _* "=" _*)
     (_* (* ["\n \t"])) ; 0 or more white space
     (_ (+ ["\n \t"])) ; 1 or more white space
     (digits (+ [0-9])))
    (swap-regions alt-start alt-end src-start src-end)))


I guess a mechanism to give matched regions a name would be useful.
E.g.  (capture E NAME) would match E and store the matched region with
NAME in a hashtable.  Actions could than easily refer to that region by
looking in the hashtable.  Auxiliary functions like (capture-string NAME)
or (capture-beginning NAME) to lookup the matched string resp. start
position in the hypothetical capture table could be implemented on top
of that.  Also something like replace-capture would then be easy to add.

Helmut.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]