1 ;;; wisent-expr.el --- Infix to prefix expression converter
3 ;; Copyright (C) 2001 David Ponce
5 ;; Author: David Ponce <david@dponce.com>
6 ;; Maintainer: David Ponce <david@dponce.com>
7 ;; Created: 19 June 2001
9 ;; X-RCS: $Id: wisent-expr.el,v 1.1 2007-11-26 15:12:31 michaels Exp $
11 ;; This file is not part of GNU Emacs.
13 ;; This program is free software; you can redistribute it and/or
14 ;; modify it under the terms of the GNU General Public License as
15 ;; published by the Free Software Foundation; either version 2, or (at
16 ;; your option) any later version.
18 ;; This program is distributed in the hope that it will be useful, but
19 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 ;; General Public License for more details.
23 ;; You should have received a copy of the GNU General Public License
24 ;; along with this program; see the file COPYING. If not, write to
25 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26 ;; Boston, MA 02110-1301, USA.
30 ;; Sample program using the elisp LALR parser Wisent. It just converts
31 ;; expressions from infix (C like) to prefix notation (Lisp like).
40 (defconst wisent-expr-parser-tables
42 (wisent-compile-grammar
45 (NUMBER MINUS PLUS DIV MULT LPAREN RPAREN SEMI)
46 ;; no operator precedence
49 (grammar ((grammar expr)
50 (format "%s %s" $1 $2))
55 (format "%s%s" $1 $2))
58 ((error SEMI) ;; on parse error skip tokens until
59 "\"error\";") ;; next semicolon and return "error";
61 (add ((add MINUS mult)
67 (mult ((mult DIV final)
73 (final ((LPAREN add RPAREN)
78 "Expression converter parser tables.")
80 (defconst wisent-expr-operators
88 "Expression converter operator terminals.")
90 (defconst wisent-expr-number-regexp
93 "[0-9]+\\([.][0-9]*\\)?\\([eE][-+]?[0-9]+\\)?"
95 "[.][0-9]+\\([eE][-+]?[0-9]+\\)?"
98 "Regexp to match the expression converter number terminals.")
100 (defvar wisent-expr-lexer-input-stream nil
101 "The expression converter lexer input stream.")
103 (defun wisent-expr-lexer ()
104 "The expression converter lexer."
105 (let* ((is (or wisent-expr-lexer-input-stream ""))
106 (k (string-match "\\S-" is)) ;; skip spaces
107 (lex (list wisent-eoi-term)))
110 (setq is (substring is k))
113 ((string-match wisent-expr-number-regexp is)
114 (setq lex (list 'NUMBER (read (match-string 0 is)))
115 is (substring is (match-end 0))))
117 ((setq k (assq (aref is 0) wisent-expr-operators))
118 (setq lex (list (cdr k) (string (aref is 0)))
119 is (substring is 1)))
122 (error "Invalid input character '%c'" (aref is 0))))
123 (setq wisent-expr-lexer-input-stream is))
126 (defun wisent-expr (input)
127 "Infix to prefix expression converter.
128 Parse INPUT string and output the result of computation."
129 (interactive "sexpr: ")
130 (or (string-match ";\\s-*$" input)
131 (setq input (concat input ";")))
132 (let ((wisent-expr-lexer-input-stream input))
135 (wisent-parse wisent-expr-parser-tables
139 (provide 'wisent-expr)
141 ;;; wisent-expr.el ends here