chiark / gitweb /
src/module-parse.lisp: Abstract out `parse-maybe-dotted-name'.
[sod] / src / module-parse.lisp
index e175a5b3ffe1be8d2ab4d6952577d80ffb7d5985..fb60b4947b3b12d331372ded8fab51659da60277 100644 (file)
@@ -277,23 +277,23 @@ (defun parse-class-body (scanner pset name supers)
                                  pset scanner))
           (nick (sod-class-nickname class)))
 
-      (labels ((parse-maybe-dotted-declarator (base-type)
-                ;; Parse a declarator or dotted-declarator, i.e., one whose
-                ;; centre is
-                ;;
-                ;; maybe-dotted-identifier ::= [id `.'] id
+      (labels ((parse-maybe-dotted-name ()
+                ;; maybe-dotted-name ::= [id `.'] id
                 ;;
                 ;; A plain identifier is returned as a string, as usual; a
                 ;; dotted identifier is returned as a cons cell of the two
                 ;; names.
-                (parse-declarator
-                 scanner base-type
-                 :keywordp t
-                 :kernel (parser ()
-                           (seq ((name-a :id)
-                                 (name-b (? (seq (#\. (id :id)) id))))
-                             (if name-b (cons name-a name-b)
-                                 name-a)))))
+                (parse (seq ((name-a :id)
+                             (name-b (? (seq (#\. (id :id)) id))))
+                         (if name-b (cons name-a name-b)
+                             name-a))))
+
+              (parse-maybe-dotted-declarator (base-type)
+                ;; Parse a declarator or dotted-declarator, i.e., one whose
+                ;; centre is maybe-dotted-name above.
+                (parse-declarator scanner base-type
+                                  :keywordp t
+                                  :kernel #'parse-maybe-dotted-name))
 
               (parse-message-item (sub-pset type name)
                 ;; message-item ::=
@@ -317,15 +317,17 @@ (defun parse-class-body (scanner pset name supers)
                 (parse (seq ((body (or (seq ("extern" #\;) nil)
                                        (parse-delimited-fragment
                                         scanner #\{ #\}))))
-                         (make-sod-method class sub-nick name type
-                                          body sub-pset scanner))))
+                         (restart-case
+                             (make-sod-method class sub-nick name type
+                                              body sub-pset scanner)
+                           (continue () :report "Continue")))))
 
               (parse-initializer ()
                 ;; initializer ::= `=' c-fragment
                 ;;
                 ;; Return a VALUE, ready for passing to a `sod-initializer'
                 ;; constructor.
-                (parse-delimited-fragment scanner #\= (list #\, #\;)
+                (parse-delimited-fragment scanner #\= '(#\, #\;)
                                           :keep-end t))
 
               (parse-slot-item (sub-pset base-type type name)
@@ -334,24 +336,27 @@ (defun parse-class-body (scanner pset name supers)
                 ;;             [`,' list[init-declarator]] `;'
                 ;;
                 ;; init-declarator ::= declarator [initializer]
-                (parse (and (seq ((init (? (parse-initializer))))
-                              (make-sod-slot class name type
-                                             sub-pset scanner)
-                              (when init
-                                (make-sod-instance-initializer
-                                 class nick name init sub-pset scanner)))
-                            (skip-many ()
-                              (seq (#\,
-                                    (ds (parse-declarator scanner
-                                                          base-type))
-                                    (init (? (parse-initializer))))
-                                (make-sod-slot class (cdr ds) (car ds)
-                                               sub-pset scanner)
-                                (when init
-                                  (make-sod-instance-initializer
-                                   class nick (cdr ds) init
-                                   sub-pset scanner))))
-                            #\;)))
+                (flet ((make-it (name type init)
+                         (restart-case
+                             (progn
+                               (make-sod-slot class name type
+                                              sub-pset scanner)
+                               (when init
+                                 (make-sod-instance-initializer class
+                                                                nick name
+                                                                init
+                                                                sub-pset
+                                                                scanner)))
+                           (continue () :report "Continue"))))
+                  (parse (and (seq ((init (? (parse-initializer))))
+                                (make-it name type init))
+                              (skip-many ()
+                                (seq (#\,
+                                      (ds (parse-declarator scanner
+                                                            base-type))
+                                      (init (? (parse-initializer))))
+                                  (make-it (cdr ds) (car ds) init)))
+                              #\;))))
 
               (parse-initializer-item (sub-pset must-init-p constructor)
                 ;; initializer-item ::=
@@ -363,9 +368,11 @@ (defun parse-class-body (scanner pset name supers)
                   (parse (and (skip-many ()
                                 (seq ((name-a :id) #\. (name-b :id)
                                       (init (funcall parse-init)))
-                                  (funcall constructor class
-                                           name-a name-b init
-                                           sub-pset scanner))
+                                  (restart-case
+                                      (funcall constructor class
+                                               name-a name-b init
+                                               sub-pset scanner)
+                                    (continue () :report "Continue")))
                                 #\,)
                               #\;))))