Commits

Anonymous committed fa80637

Added defparser helper to define grammar & lexer at once (delegates to defgrammar and lexer), and added source-text convenience accessors on parser & lexer. For example, after defining a parser, can use source-text to define what text to parse.

Comments (0)

Files changed (2)

 ;;
 ;; ---------------------------------------------------------------------------------------------------------------------
 
+;; Source code helpers
+(defmethod source-text ((lexer lexer))
+  (source-text (source lexer)))
+
+(defmethod (setf source-text) (text (lexer lexer) )
+  ;; Drop existing lines
+  (setf (source-text (source lexer)) text))
+
 (defmacro deflexer (name (&optional (initial-state nil)) &rest token-definitions)
   "Define a lexer whose class is the provided name, the initial state of the lexer is initial,
 and token definitions are a set of rules defining the tokens recognized by the lexer.  Token definitions should be
    (lexer :initarg :lexer :accessor lexer)
    (stack :initform () :accessor stack)))
 
+
+;; Source code helper
+(defmethod source-text ((parser lalr1-parser))
+  (source-text (lexer parser)))
+
+(defmethod (setf source-text) (text (parser lalr1-parser) )
+  ;; Drop existing lines
+  (setf (source-text (lexer parser)) text))
+
 (defun expected-next-symbols (parser)
   "Given a parser's current state, return a list of valid symbols (terminal and non-terminal) that would advance the parse"
   (let ((state (caar (stack parser)))
        while (equal :continue result)
        finally (return (values result (get-parse-result parser))))))
 
+;; ---------------------------------------------------------------------------------------------------------------------
+;;
+
+(defmacro defparser (name &key grammar lexer)
+  (let ((parser-factory (intern (format nil "MAKE-~a-PARSER" name) (symbol-package name)))
+	(grammar-name (intern (format nil "~a-GRAMMAR" name) (symbol-package name)))
+	(lexer-name (intern (format nil "~a-LEXER" name) (symbol-package name))))
+    `(progn 
+
+       (defgrammar ,grammar-name
+	   ,@grammar)
+
+       (deflexer ,lexer-name
+	   ,@lexer)
+
+       (defun ,parser-factory ()
+	 (let ((grammar (,grammar-name))
+	       (lexer (make-instance ',lexer-name)))
+	   (make-parser lexer grammar))))))