Function: semantic-bovinate-stream
semantic-bovinate-stream is an autoloaded and byte-compiled function
defined in bovine.el.gz.
Signature
(semantic-bovinate-stream STREAM &optional NONTERMINAL)
Documentation
Bovinate STREAM, starting at the first NONTERMINAL rule.
Use bovine-toplevel if NONTERMINAL is not provided.
This is the core routine for converting a stream into a table.
Return the list (STREAM SEMANTIC-STREAM) where STREAM are those
elements of STREAM that have not been used. SEMANTIC-STREAM is the
list of semantic tokens found.
Aliases
Source Code
;; Defined in /usr/src/emacs/lisp/cedet/semantic/bovine.el.gz
;;;###autoload
(defun semantic-bovinate-stream (stream &optional nonterminal)
"Bovinate STREAM, starting at the first NONTERMINAL rule.
Use `bovine-toplevel' if NONTERMINAL is not provided.
This is the core routine for converting a stream into a table.
Return the list (STREAM SEMANTIC-STREAM) where STREAM are those
elements of STREAM that have not been used. SEMANTIC-STREAM is the
list of semantic tokens found."
(if (not nonterminal)
(setq nonterminal 'bovine-toplevel))
;; Try to detect infinite recursive parse when doing a full reparse.
(or semantic--buffer-cache
(semantic-bovinate-nonterminal-check stream nonterminal))
;; FIXME: `semantic-parse-region-c-mode' inspects `lse' to try and
;; detect a recursive call (used with macroexpansion, to avoid inf-loops).
(with-suppressed-warnings ((lexical lse)) (defvar lse))
(let* ((table semantic--parse-table)
(matchlist (cdr (assq nonterminal table)))
(starting-stream stream)
(nt-loop t) ;non-terminal loop condition
nt-popup ;non-nil if return from nt recursion
nt-stack ;non-terminal recursion stack
s ;Temp Stream Tracker
lse ;Local Semantic Element
lte ;Local matchlist element
tev ;Matchlist entry values from buffer
val ;Value found in buffer.
cvl ;collected values list.
out ;Output
end ;End of match
result
)
(condition-case debug-condition
(while nt-loop
(catch 'push-non-terminal
(setq nt-popup nil
end (semantic-lex-token-end (car stream)))
(while (or nt-loop nt-popup)
(setq nt-loop nil
out nil)
(while (or nt-popup matchlist)
(if nt-popup
;; End of a non-terminal recursion
(setq nt-popup nil)
;; New matching process
(setq s stream ;init s from stream.
cvl nil ;re-init the collected value list.
lte (car matchlist) ;Get the local matchlist entry.
)
(if (or (compiled-function-p (car lte))
(listp (car lte)))
;; In this case, we have an EMPTY match! Make
;; stuff up.
(setq cvl (list nil))))
(while (and lte
(not (compiled-function-p (car lte)))
(not (listp (car lte))))
;; GRAMMAR SOURCE DEBUGGING!
(if (and (boundp 'semantic-debug-enabled)
semantic-debug-enabled)
(let* ((db-nt (semantic-bovinate-nonterminal-db-nt))
(db-ml (cdr (assq db-nt table)))
(db-mlen (length db-ml))
(db-midx (- db-mlen (length matchlist)))
(db-tlen (length (nth db-midx db-ml)))
(db-tidx (- db-tlen (length lte)))
(frame (progn
(require 'semantic/bovine/debug)
(semantic-bovine-debug-create-frame
db-nt db-midx db-tidx cvl (car s))))
(cmd (semantic-debug-break frame))
)
(cond ((eq 'fail cmd) (setq lte '(trash 0 . 0)))
((eq 'quit cmd) (signal 'quit "Abort"))
((eq 'abort cmd) (error "Abort"))
;; support more commands here.
)))
;; END GRAMMAR SOURCE DEBUGGING!
(cond
;; We have a nonterminal symbol. Recurse inline.
((setq nt-loop (assq (car lte) table))
(setq
;; push state into the nt-stack
nt-stack (cons (vector matchlist cvl lte stream end
)
nt-stack)
;; new non-terminal matchlist
matchlist (cdr nt-loop)
;; new non-terminal stream
stream s)
(throw 'push-non-terminal t)
)
;; Default case
(t
(setq lse (car s) ;Get the local stream element
s (cdr s)) ;update stream.
;; Do the compare
(if (eq (car lte) (semantic-lex-token-class lse)) ;syntactic match
(let ((valdot (semantic-lex-token-bounds lse)))
(setq val (semantic-lex-token-text lse))
(setq lte (cdr lte))
(if (stringp (car lte))
(progn
(setq tev (car lte)
lte (cdr lte))
(if (string-match tev val)
(setq cvl (cons
(if (memq (semantic-lex-token-class lse)
'(comment semantic-list))
valdot val)
cvl)) ;append this value
(setq lte nil cvl nil))) ;clear the entry (exit)
(setq cvl (cons
(if (memq (semantic-lex-token-class lse)
'(comment semantic-list))
valdot val)
cvl))) ;append unchecked value.
(setq end (semantic-lex-token-end lse))
)
(setq lte nil cvl nil)) ;No more matches, exit
)))
(if (not cvl) ;lte=nil; there was no match.
(setq matchlist (cdr matchlist)) ;Move to next matchlist entry
(let ((start (semantic-lex-token-start (car stream))))
(setq out (cond
((car lte)
(funcall (car lte) ;call matchlist fn on values
(nreverse cvl) start end))
((and (= (length cvl) 1)
(listp (car cvl))
(not (numberp (car (car cvl)))))
(append (car cvl) (list start end)))
(t
;;(append (nreverse cvl) (list start end))))
;; MAYBE THE FOLLOWING NEEDS LESS CONS
;; CELLS THAN THE ABOVE?
(nreverse (cons end (cons start cvl)))))
matchlist nil) ;;generate exit condition
(if (not end)
(setq out nil)))
;; Nothing?
))
(setq result
(if (eq s starting-stream)
(list (cdr s) nil)
(list s out)))
(if nt-stack
;; pop previous state from the nt-stack
(let ((state (car nt-stack)))
(setq nt-popup t
;; pop actual parser state
matchlist (aref state 0)
cvl (aref state 1)
lte (aref state 2)
stream (aref state 3)
end (aref state 4)
;; update the stack
nt-stack (cdr nt-stack))
(if out
(let ((len (length out))
(strip (nreverse (cdr (cdr (reverse out))))))
(setq end (nth (1- len) out) ;reset end to the end of exp
cvl (cons strip cvl) ;prepend value of exp
lte (cdr lte)) ;update the local table entry
)
;; No value means that we need to terminate this
;; match.
(setq lte nil cvl nil)) ;No match, exit
)))))
(error
;; On error just move forward the stream of lexical tokens
(setq result (list (cdr starting-stream) nil))
(when (and (boundp 'semantic-debug-enabled)
semantic-debug-enabled)
(require 'semantic/bovine/debug)
(let ((frame (semantic-create-bovine-debug-error-frame
debug-condition)))
(semantic-debug-break frame)))))
result))