Function: wisent-parse
wisent-parse is a byte-compiled function defined in wisent.el.gz.
Signature
(wisent-parse AUTOMATON LEXER &optional ERROR START)
Documentation
Parse input using the automaton specified in AUTOMATON.
- AUTOMATON is an LALR(1) automaton generated by
wisent-compile-grammar.
- LEXER is a function with no argument called by the parser to obtain
the next terminal (token) in input.
- ERROR is an optional reporting function called when a parse error
occurs. It receives a message string to report. It defaults to the
function wisent-message.
- START specify the start symbol (nonterminal) used by the parser as
its goal. It defaults to the start symbol defined in the grammar
(see also wisent-compile-grammar).
Source Code
;; Defined in /usr/src/emacs/lisp/cedet/semantic/wisent/wisent.el.gz
(defun wisent-parse (automaton lexer &optional error start)
"Parse input using the automaton specified in AUTOMATON.
- AUTOMATON is an LALR(1) automaton generated by
`wisent-compile-grammar'.
- LEXER is a function with no argument called by the parser to obtain
the next terminal (token) in input.
- ERROR is an optional reporting function called when a parse error
occurs. It receives a message string to report. It defaults to the
function `wisent-message'.
- START specify the start symbol (nonterminal) used by the parser as
its goal. It defaults to the start symbol defined in the grammar
(see also `wisent-compile-grammar')."
(run-hooks 'wisent-pre-parse-hook)
(let* ((actions (aref automaton 0))
(gotos (aref automaton 1))
(starts (aref automaton 2))
(stack (make-vector wisent-parse-max-stack-size nil))
(sp 0)
(wisent-loop t)
(wisent-parse-error-function (or error 'wisent-message))
(wisent-parse-lexer-function lexer)
(wisent-recovering nil)
(wisent-input (wisent-parse-start start starts))
state tokid choices choice)
(setq wisent-nerrs 0 ;; Reset parse error counter
wisent-lookahead nil) ;; and lookahead token
(aset stack 0 0) ;; Initial state
(while wisent-loop
(setq state (aref stack sp)
tokid (car wisent-input)
wisent-loop (wisent-parse-action tokid (aref actions state)))
(cond
;; Input successfully parsed
;; -------------------------
((eq wisent-loop wisent-accept-tag)
(setq wisent-loop nil))
;; Syntax error in input
;; ---------------------
((eq wisent-loop wisent-error-tag)
;; Report this error if not already recovering from an error.
(setq choices (aref actions state))
(or wisent-recovering
(wisent-error
(format "Syntax error, unexpected %s, expecting %s"
(wisent-token-to-string wisent-input)
(mapconcat #'wisent-item-to-string
(delq wisent-error-term
(mapcar #'car (cdr choices)))
", "))))
;; Increment the error counter
(setq wisent-nerrs (1+ wisent-nerrs))
;; If just tried and failed to reuse lookahead token after an
;; error, discard it.
(if (eq wisent-recovering wisent-parse-max-recover)
(if (eq tokid wisent-eoi-term)
(wisent-abort) ;; Terminate if at end of input.
(wisent-message "Error recovery: skip %s"
(wisent-token-to-string wisent-input))
(run-hook-with-args
'wisent-discarding-token-functions wisent-input)
(setq wisent-input (wisent-lexer)))
;; Else will try to reuse lookahead token after shifting the
;; error token.
;; Each real token shifted decrements this.
(setq wisent-recovering wisent-parse-max-recover)
;; Pop the value/state stack to see if an action associated
;; to special terminal symbol 'error exists.
(while (and (>= sp 0)
(not (and (setq state (aref stack sp)
choices (aref actions state)
choice (assq wisent-error-term choices))
(natnump (cdr choice)))))
(setq sp (- sp 2)))
(if (not choice)
;; No 'error terminal was found. Just terminate.
(wisent-abort)
;; Try to recover and continue parsing.
;; Shift the error terminal.
(setq state (cdr choice) ; new state
sp (+ sp 2))
(aset stack (1- sp) nil) ; push value
(aset stack sp state) ; push new state
;; Adjust input to error recovery state. Unless 'error
;; triggers a reduction, eat the input stream until an
;; expected terminal symbol is found, or EOI is reached.
(if (cdr (setq choices (aref actions state)))
(while (not (or (eq (car wisent-input) wisent-eoi-term)
(assq (car wisent-input) choices)))
(wisent-message "Error recovery: skip %s"
(wisent-token-to-string wisent-input))
(run-hook-with-args
'wisent-discarding-token-functions wisent-input)
(setq wisent-input (wisent-lexer)))))))
;; Shift current token on top of the stack
;; ---------------------------------------
((natnump wisent-loop)
;; Count tokens shifted since error; after
;; `wisent-parse-max-recover', turn off error status.
(setq wisent-recovering (and (natnump wisent-recovering)
(> wisent-recovering 1)
(1- wisent-recovering)))
(setq sp (+ sp 2))
(aset stack (1- sp) (cdr wisent-input))
(aset stack sp wisent-loop)
(setq wisent-input (wisent-lexer)))
;; Reduce by rule (call semantic action)
;; -------------------------------------
(t
(setq sp (funcall wisent-loop stack sp gotos))
(or wisent-input (setq wisent-input (wisent-lexer))))))
(run-hooks 'wisent-post-parse-hook)
(car (aref stack 1))))