Commits

Anonymous committed 06f4c20

New defparser keyword: :RESERVED-TERMINALS
Keywords: reserved-terminals, defparser, reserved-terminals

* fg-macro.lisp (fucc:defparser):
New keyword is defined and handled.

* MACRO:
New keyword is documented.

Comments (0)

Files changed (2)

 -*- mode: outline; -*-
 
 Macro FUCC:DEFPARSER variable initial (&rest terminals) (&rest rules)
-                     &key prec-info
+                     &key reserved-terminals
+                          prec-info
                           (type :lalr)
                           lexer-options
 
 
 Keywords:
 
+* :RESERVED-TERMINALS
+  List of terminals that are reserved, i.e. are not used by current
+  grammar, but defined by language.  If there are some terminals that
+  are not declared reserved but unused, warning is signaled.  If some
+  reserved terminals are used, another warning is signaled.
+
 * :PREC-INFO
 
 Precedence info.  Argument is list of prec-lists.  Each prec-list

generator/fg-macro.lisp

 (in-package #:fucc-generator)
 
 (defmacro fucc:defparser (variable initial (&rest terminals) (&rest rules)
-                          &key prec-info
+                          &key reserved-terminals
+                               prec-info
                                (type :lalr)
                                lexer-options)
   (let ((grammar (parse-grammar initial terminals rules :prec-info prec-info))
         (setf unproductive
               (sort unproductive #'nterm<=))
         (warn "Unproductive nonterminals:~%~{ ~S~}"
-              unproductive))
-      (when unused
-        (setf unused (sort unused #'nterm<=))
-        (warn "Unused (non)terminals:~%~{ ~S~}"
-              unused))
+              (mapcar #'nterm-name unproductive)))
+
+      (let ((unused-names (mapcar #'nterm-name unused)))
+        (let ((unused-by-mistake
+               (set-difference unused-names reserved-terminals))
+              (used-by-mistake
+               (set-difference reserved-terminals unused-names)))
+          (when unused-by-mistake
+            (warn "Unused (non)terminals:~%~{ ~S~}" unused-by-mistake))
+          (when used-by-mistake
+            (warn "Used reserved terminals:~%~{ ~S~}" used-by-mistake))))
       (when (or unproductive unused)
         ;; Recalculate grammar properties
         (loop :for idx :from 0