wisent: Mixed style

 
 4.1.3 Mixed style
 -----------------
 
      %start grammar
      ;; Reparse
      %start prologue epilogue declaration nonterminal rule
      ...
 
      %%
 
      grammar:
          prologue
        | epilogue
        | declaration
        | nonterminal
        | PERCENT_PERCENT
        ;
      ...
 
      nonterminal:
          SYMBOL COLON rules SEMI
          (TAG $1 'nonterminal :children $3)
        ;
 
      rules:
          lifo_rules
          (apply 'nconc (nreverse $1))
        ;
 
      lifo_rules:
          lifo_rules OR rule
          (cons $3 $1)
        | rule
          (list $1)
        ;
 
      rule:
          rhs
          (let* ((rhs $1)
                 name type comps prec action elt)
            ...
            (EXPANDTAG
             (TAG name 'rule :type type :value comps :prec prec :expr action)
             ))
        ;
 
    This example shows how iterative and Bison styles can be combined in
 the same grammar to obtain a good compromise between grammar complexity
 and an efficient parsing strategy in an interactive environment.
 
    ‘nonterminal’ is parsed using iterative style via the main ‘grammar’
 rule.  The semantic action uses the ‘TAG’ macro to produce a raw tag,
 automagically expanded by Semantic.
 
    But ‘rules’ part is parsed in Bison style!  Why?
 
    Rule delimiters are the colon (‘:’), that follows the nonterminal
 name, and a final semicolon (‘;’).  Unfortunately these delimiters are
 not ‘open-paren’/‘close-paren’ type, and the Emacs’ syntactic analyzer
 can’t easily isolate data between them to produce a ‘RULES_PART’
 parenthesis-block-like lexical token.  Consequently it is not possible
 to use ‘EXPANDFULL’ to iterate in ‘RULES_PART’, like this:
 
      nonterminal:
          SYMBOL COLON rules SEMI
          (TAG $1 'nonterminal :children $3)
        ;
 
      rules:
          RULES_PART  ;; *Map a parenthesis-block-like lexical token*
          (EXPANDFULL $1 'rules)
        ;
 
      rules:
          COLON
          ()
          OR
          ()
          SEMI
          ()
          rhs
          rhs
          (let* ((rhs $1)
                 name type comps prec action elt)
            ...
            (TAG name 'rule :type type :value comps :prec prec :expr action)
            )
        ;
 
    In such cases, when it is difficult for Emacs to obtain
 parenthesis-block-like lexical tokens, the best solution is to use the
 traditional Bison style with error recovery!
 
    In some extreme cases, it can also be convenient to extend the lexer,
 to deliver new lexical tokens, to simplify the grammar.