Function: define-lex-block-type-analyzer

define-lex-block-type-analyzer is a macro defined in lex.el.gz.

Signature

(define-lex-block-type-analyzer NAME DOC SYNTAX MATCHES)

Documentation

Define a block type analyzer NAME with DOC string.

SYNTAX is the regexp that matches block delimiters, typically the open (\\s() and close (\\s)) parenthesis syntax classes.

MATCHES is a pair (OPEN-SPECS . CLOSE-SPECS) that defines blocks.

  OPEN-SPECS is a list of (OPEN-DELIM OPEN-TOKEN BLOCK-TOKEN) elements
  where:

    OPEN-DELIM is a string: the block open delimiter character.

    OPEN-TOKEN is the lexical token class associated to the OPEN-DELIM
    delimiter.

    BLOCK-TOKEN is the lexical token class associated to the block
    that starts at the OPEN-DELIM delimiter.

  CLOSE-SPECS is a list of (CLOSE-DELIM CLOSE-TOKEN) elements where:

    CLOSE-DELIM is a string: the block end delimiter character.

    CLOSE-TOKEN is the lexical token class associated to the
    CLOSE-DELIM delimiter.

Each element in OPEN-SPECS must have a corresponding element in CLOSE-SPECS.

The lexer will return a BLOCK-TOKEN token when the value of semantic-lex-current-depth is greater than or equal to the maximum depth of parenthesis tracking (see also the function semantic-lex). Otherwise it will return OPEN-TOKEN and CLOSE-TOKEN tokens.

TO DO: Put the following in the developer's guide and just put a reference here.

In the grammar:

The value of a block token must be a string that contains a readable sexp of the form:

  "(OPEN-TOKEN CLOSE-TOKEN)"

OPEN-TOKEN and CLOSE-TOKEN represent the block delimiters, and must be lexical tokens of respectively open-paren and close-paren types. Their value is the corresponding delimiter character as a string.

Here is a small example to analyze a parenthesis block:

  %token <block> PAREN_BLOCK "(LPAREN RPAREN)"
  %token <open-paren> LPAREN "("
  %token <close-paren> RPAREN ")"

When the lexer encounters the open-paren delimiter "(":

 - If the maximum depth of parenthesis tracking is not reached (that
   is, current depth < max depth), it returns a (LPAREN start . end)
   token, then continue analysis inside the block. Later, when the
   corresponding close-paren delimiter ")" will be encountered, it
   will return a (RPAREN start . end) token.

 - If the maximum depth of parenthesis tracking is reached (current
   depth >= max depth), it returns the whole parenthesis block as
   a (PAREN_BLOCK start . end) token.

Source Code

;; Defined in /usr/src/emacs/lisp/cedet/semantic/lex.el.gz
(defmacro define-lex-block-type-analyzer (name doc syntax matches)
  "Define a block type analyzer NAME with DOC string.

SYNTAX is the regexp that matches block delimiters, typically the
open (`\\\\s(') and close (`\\\\s)') parenthesis syntax classes.

MATCHES is a pair (OPEN-SPECS . CLOSE-SPECS) that defines blocks.

  OPEN-SPECS is a list of (OPEN-DELIM OPEN-TOKEN BLOCK-TOKEN) elements
  where:

    OPEN-DELIM is a string: the block open delimiter character.

    OPEN-TOKEN is the lexical token class associated to the OPEN-DELIM
    delimiter.

    BLOCK-TOKEN is the lexical token class associated to the block
    that starts at the OPEN-DELIM delimiter.

  CLOSE-SPECS is a list of (CLOSE-DELIM CLOSE-TOKEN) elements where:

    CLOSE-DELIM is a string: the block end delimiter character.

    CLOSE-TOKEN is the lexical token class associated to the
    CLOSE-DELIM delimiter.

Each element in OPEN-SPECS must have a corresponding element in
CLOSE-SPECS.

The lexer will return a BLOCK-TOKEN token when the value of
`semantic-lex-current-depth' is greater than or equal to the maximum
depth of parenthesis tracking (see also the function `semantic-lex').
Otherwise it will return OPEN-TOKEN and CLOSE-TOKEN tokens.

TO DO: Put the following in the developer's guide and just put a
reference here.

In the grammar:

The value of a block token must be a string that contains a readable
sexp of the form:

  \"(OPEN-TOKEN CLOSE-TOKEN)\"

OPEN-TOKEN and CLOSE-TOKEN represent the block delimiters, and must be
lexical tokens of respectively `open-paren' and `close-paren' types.
Their value is the corresponding delimiter character as a string.

Here is a small example to analyze a parenthesis block:

  %token <block>       PAREN_BLOCK \"(LPAREN RPAREN)\"
  %token <open-paren>  LPAREN      \"(\"
  %token <close-paren> RPAREN      \")\"

When the lexer encounters the open-paren delimiter \"(\":

 - If the maximum depth of parenthesis tracking is not reached (that
   is, current depth < max depth), it returns a (LPAREN start .  end)
   token, then continue analysis inside the block.  Later, when the
   corresponding close-paren delimiter \")\" will be encountered, it
   will return a (RPAREN start . end) token.

 - If the maximum depth of parenthesis tracking is reached (current
   depth >= max depth), it returns the whole parenthesis block as
   a (PAREN_BLOCK start . end) token."
  (declare (indent 1))
  (let* ((val (make-symbol "val"))
         (lst (make-symbol "lst"))
         (elt (make-symbol "elt")))
    `(define-lex-analyzer ,name
       ,doc
       (and
        (looking-at ,syntax) ;; "\\(\\s(\\|\\s)\\)"
        (let ((,val (match-string 0))
              (,lst ,matches)
              ,elt)
          (cond
           ((setq ,elt (assoc ,val (car ,lst)))
            (if (or (not semantic-lex-maximum-depth)
                    (< semantic-lex-current-depth semantic-lex-maximum-depth))
                (progn
                  (setq semantic-lex-current-depth (1+ semantic-lex-current-depth))
                  (semantic-lex-push-token
                   (semantic-lex-token
                    (nth 1 ,elt)
                    (match-beginning 0) (match-end 0))))
              (semantic-lex-push-token
               (semantic-lex-token
                (nth 2 ,elt)
                (match-beginning 0)
                (save-excursion
                  (semantic-lex-unterminated-syntax-protection (nth 2 ,elt)
                    (forward-list 1)
                    (point)))))))
           ((setq ,elt (assoc ,val (cdr ,lst)))
            (setq semantic-lex-current-depth (1- semantic-lex-current-depth))
            (semantic-lex-push-token
             (semantic-lex-token
              (nth 1 ,elt)
              (match-beginning 0) (match-end 0))))
           ))))
    ))