Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Recursive descent parser for Emacs Lisp

branch: master
README.md

Recursive Descent Parser for Emacs Lisp

This package provides a recursive descent parser for Elisp programs. Grammars are specified using a pure Elisp s-expression. A set of matching functions can be provided to the parser to manipulate the parse tree at read time. These functions can even be used to implement a compiler.

The parser will indicate where the point is in the parse tree, for use in automatic indentation for major modes. This is no silver bullet: automatic indentation is still a black art]. SMIE is probably better suited if that's your goal -- to implement indentation but not fully parse a language as rdp would.

Full documentation can be found in the commentary section of rdp.el.

Example

This is an interpreter for simple arithmetic expressions, including operator precedence and grouping.

(defvar arith-tokens
  '((sum       prod  [([+ -] sum)  no-sum])
    (prod      value [([* /] prod) no-prod])
    (num     . "-?[0-9]+\\(\\.[0-9]*\\)?")
    (+       . "\\+")
    (-       . "-")
    (*       . "\\*")
    (/       . "/")
    (pexpr     "(" [sum prod num pexpr] ")")
    (value   . [pexpr num])
    (no-prod . "")
    (no-sum  . "")))

(defun arith-op (expr)
  (destructuring-bind (a (op b)) expr
    (funcall op a b)))

(defvar arith-funcs
  `((sum     . ,#'arith-op)
    (prod    . ,#'arith-op)
    (num     . ,#'string-to-number)
    (+       . ,#'intern)
    (-       . ,#'intern)
    (*       . ,#'intern)
    (/       . ,#'intern)
    (pexpr   . ,#'cadr)
    (value   . ,#'identity)
    (no-prod . ,(lambda (e) '(* 1)))
    (no-sum  . ,(lambda (e) '(+ 0)))))

(defun arith (string)
  (rdp-parse-string string arith-tokens arith-funcs))

Usage:

(arith "(1 + 2 + 3 * 4)*-3/4.0")

This evaluates to -11.25, as would be expected.

See Also

Something went wrong with that request. Please try again.