[climacs-cvs] CVS update: climacs/syntax.lisp
Christophe Rhodes
crhodes at common-lisp.net
Thu Apr 14 08:13:19 UTC 2005
Update of /project/climacs/cvsroot/climacs
In directory common-lisp.net:/tmp/cvs-serv12616
Modified Files:
syntax.lisp
Log Message:
slight improvement in speed to syntax.lisp (though not enough):
Cache in the grammar which rules are applicable to which symbols.
Make ITEM-EQUAL a regular function.
A couple of folorn (optimize speed)s and type declarations, which don't
actually help all that much.
Date: Thu Apr 14 10:13:18 2005
Author: crhodes
Index: climacs/syntax.lisp
diff -u climacs/syntax.lisp:1.41 climacs/syntax.lisp:1.42
--- climacs/syntax.lisp:1.41 Fri Mar 18 08:49:17 2005
+++ climacs/syntax.lisp Thu Apr 14 10:13:18 2005
@@ -207,7 +207,8 @@
(symbols :initarg :symbols :reader symbols)))
(defclass grammar ()
- ((rules :initarg :rules :accessor rules)))
+ ((rules :initform nil :accessor rules)
+ (hash :initform (make-hash-table) :accessor hash)))
(defmacro grammar-rule ((left-hand-side arrow arglist &body body))
(declare (ignore arrow))
@@ -245,14 +246,29 @@
(defmacro grammar (&body body)
- `(make-instance 'grammar
- :rules (list ,@(loop for rule in body
- collect `(grammar-rule ,rule)))))
+ (let ((rule (gensym "RULE"))
+ (rules (gensym "RULES"))
+ (result (gensym "RESULT")))
+ `(let* ((,rules (list ,@(loop for rule in body
+ collect `(grammar-rule ,rule))))
+ (,result (make-instance 'grammar)))
+ (dolist (,rule ,rules ,result)
+ (add-rule ,rule ,result)))))
(defgeneric add-rule (rule grammar))
(defmethod add-rule (rule (grammar grammar))
- (push rule (rules grammar)))
+ (push rule (rules grammar))
+ (clrhash (hash grammar))
+ (let (rhs-symbols)
+ (dolist (rule (rules grammar))
+ (setf rhs-symbols (union rhs-symbols (coerce (symbols rule) 'list))))
+ (dolist (rule (rules grammar))
+ (let ((lhs-symbol (left-hand-side rule)))
+ (dolist (rhs-symbol rhs-symbols)
+ (when (or (subtypep lhs-symbol rhs-symbol)
+ (subtypep rhs-symbol lhs-symbol))
+ (pushnew rule (gethash rhs-symbol (hash grammar)))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
@@ -316,19 +332,18 @@
:parse-tree remaining
:parse-trees parse-trees)))))))
-(defgeneric item-equal (item1 item2))
-
-(defgeneric parse-tree-equal (tree1 tree2))
-
-(defmethod item-equal ((item1 rule-item) (item2 rule-item))
- nil)
-
-(defmethod item-equal ((item1 incomplete-item) (item2 incomplete-item))
+(defun item-equal (item1 item2)
+ (declare (optimize speed))
(and (eq (rule item1) (rule item2))
- (eq (length (parse-trees item1)) (length (parse-trees item2)))
- (every #'parse-tree-equal (parse-trees item1) (parse-trees item2))))
+ (do ((trees1 (parse-trees item1) (cdr trees1))
+ (trees2 (parse-trees item2) (cdr trees2)))
+ ((and (null trees1) (null trees2)) t)
+ (when (or (null trees1) (null trees2))
+ (return nil))
+ (when (not (parse-tree-equal (car trees1) (car trees2)))
+ (return nil)))))
-(defmethod parse-tree-equal (tree1 tree2)
+(defun parse-tree-equal (tree1 tree2)
(eq (class-of tree1) (class-of tree2)))
(defgeneric parse-tree-better (tree1 tree2))
@@ -376,25 +391,24 @@
nil)
(defmethod handle-item ((item incomplete-item) orig-state to-state)
- (cond ((find item (gethash orig-state (incomplete-items to-state))
+ (declare (optimize speed))
+ (cond ((find item (the list (gethash orig-state (incomplete-items to-state)))
:test #'item-equal)
nil)
(t
(push item (gethash orig-state (incomplete-items to-state)))
- (loop for rule in (rules (parser-grammar (parser to-state)))
- do (when (let ((sym1 (aref (symbols (rule item)) (dot-position item)))
- (sym2 (left-hand-side rule)))
- (or (subtypep sym1 sym2) (subtypep sym2 sym1)))
- (handle-item (if (functionp (right-hand-side rule))
- (make-instance 'incomplete-item
- :orig-state to-state
- :predicted-from item
- :rule rule
- :dot-position 0
- :suffix (right-hand-side rule))
- (make-instance 'complete-item
- :parse-tree (right-hand-side rule)))
- to-state to-state)))
+ (dolist (rule (gethash (aref (symbols (rule item)) (dot-position item))
+ (hash (parser-grammar (parser to-state)))))
+ (handle-item (if (functionp (right-hand-side rule))
+ (make-instance 'incomplete-item
+ :orig-state to-state
+ :predicted-from item
+ :rule rule
+ :dot-position 0
+ :suffix (right-hand-side rule))
+ (make-instance 'complete-item
+ :parse-tree (right-hand-side rule)))
+ to-state to-state))
(loop for parse-tree in (gethash to-state (parse-trees to-state))
do (handle-item (derive-item item parse-tree)
to-state to-state)))))
More information about the Climacs-cvs
mailing list