Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Are you already familiar with <a href="http://en.wikipedia.org/wiki/Recursive_descent_parser" rel="noreferrer">recursive descent parsers</a>? They're relatively easy to write by hand in your favourite programming language, which would include Emacs Lisp. For very simple parsing, you can often get by with <code>looking-at</code> and <code>search-forward</code>. These would also form the basis of any <a href="http://en.wikipedia.org/wiki/Lexical_analysis" rel="noreferrer">tokenizing</a> routines that would be called by your recursive descent parser, or any other style of parser.</p> <p><strong>[11 Feb 2009]</strong> I added an example recursive descent parser in emacs lisp below. It parses simple arithmetic expressions including addition, subtraction, multiplication, division, exponentiation, and parenthesized sub-expressions. Right now, it assumes all tokens are in the global variable <code>*tokens*</code>, but if you modify <code>gettok</code> and <code>peektok</code> as necessary you can have them walk through a buffer. To use it as is, just try out the following:</p> <pre><code>(setq *token* '( 3 ^ 5 ^ 7 + 5 * 3 + 7 / 11)) (rdh/expr) =&gt; (+ (+ (^ 3 (^ 5 7)) (* 5 3)) (/ 7 11)) </code></pre> <p>The parsing code follows.</p> <pre><code>(defun gettok () (and *token* (pop *token*))) (defun peektok () (and *token* (car *token*))) (defun rdh/expr () (rdh/expr-tail (rdh/factor))) (defun rdh/expr-tail (expr) (let ((tok (peektok))) (cond ((or (null tok) (equal tok ")")) expr) ((member tok '(+ -)) (gettok) (let ((fac (rdh/factor))) (rdh/expr-tail (list tok expr fac)))) (t (error "bad expr"))))) (defun rdh/factor () (rdh/factor-tail (rdh/term))) (defun rdh/factor-tail (fac) (let ((tok (peektok))) (cond ((or (null tok) (member tok '(")" + -))) fac) ((member tok '(* /)) (gettok) (let ((term (rdh/term))) (rdh/factor-tail (list tok fac term)))) (t (error "bad factor"))))) (defun rdh/term () (let* ((prim (rdh/prim)) (tok (peektok))) (cond ((or (null tok) (member tok '(")" + - / *))) prim) ((equal tok '^) (gettok) (list tok prim (rdh/term))) (t (error "bad term"))))) (defun rdh/prim () (let ((tok (gettok))) (cond ((numberp tok) tok) ((equal tok "(") (let* ((expr (rdh/expr)) (tok (peektok))) (if (not (equal tok ")")) (error "bad parenthesized expr") (gettok) expr))) (t (error "bad prim"))))) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload