1. monoid
  2. fucc

Source

fucc / doc / MACRO

-*- mode: outline; ispell-local-dictionary: "english" -*-

Macro FUCC:DEFPARSER VARIABLE
                     INITIAL
                     (&rest TERMINALS)
                     (&rest LIST-OF-RULE-GROUPS)
                     &key RESERVED-TERMINALS
                          PREC-INFO
                          (TYPE :lalr)
                          LEXER-OPTIONS

The macro defines special VARIABLE (with DEFPARAMETER) where parser's
tables are stored.  INITIAL is symbol that designated initial
nonterminal.  TERMINALS is list of terminals that parser can accept
(they are returned by lexer).  Other symbols in rules are treated as
non-terminals.  LIST-OF-RULE-GROUPS is list of rule groups.

RULE-GROUP may describe one rule or some rules with same left side.

  ;; One rule A -> B C
  (A -> B C)

  ;; Three rules: A -> B C,  A-> epsilon and A -> D.
  (A -> B C          
     ->      ; Empty!
     -> D)

RULE-GROUP := (SYMBOL [DELIM [VAR-DESIGNATOR* ACTION-DESCRIPTION?]]+)

VAL-DESIGNATOR := (:var SYMBOL RULE-EXP)
               |  (:initarg SYMBOL RULE-EXP)
               |  RULE-EXP

ACTION-DESCRIPTION := (:call FUNCTION)
                   |  (:class CLASS)
                   |  (:do LIST-OF-FORMS)


RULE-EXP       := (CL:* RULE-EXP)
               |  (CL:+ RULE-EXP)
               |  (:MAYBE RULE-EXP)
               |  (:LIST RULE-EXP RULE-EXP)
               |  (:OR RULE-EXP+)
               |  SYMBOL

First element of RULE-GROUP is a non-terminal (symbol that is not
member of TERMINALS list), and other elements (if any) are right side
of the rule.

DELIM is a symbol that separates right side of rules.  Left side is
same for all rules in group: it is a first element of a RULE-GROUP.
DELIM may be different symbol in different rule groups, but the
separator is same within one group.  Write

  (a -> b c
     -> k l m n)

but not

  (a -> b c
     => k l m n)

If separator contains alpha character (a-z) or digit, warning is
issued.  It helps to prevent errors like lost separator:

  (a b c             ; Warning is issued here
     -> k l m n )

ACTION-DESCRIPTION describes action performed when the rule is reduced
and intermediate actions.  If last VAL-DESIGNATOR is not followed by
an ACTION-DESCRIPTION, then default final action description is
inserted: it is (CONSTANTLY NIL) for epsilon-rules, #'IDENTITY for
one-element (middle actions are ingored) rule and #'LIST for other
rules.

Value of final ACTION-DESCRIPTION (default or explicit) is treated as
semantic value of the rule.

FUNCTION here is a form that evaluates to function designator.  For
example:

  #'(lambda (a b) (cons a b))
  (lambda (x) (process x))
  #'identity
  (constantly "Mary had a little lamb")

CLASS is symbol that denotes class name.  You must not quote it.

LIST-OF-FORMS is list of forms.

:CLASS-form creates object of class CLASS, who's initargs are defined
with :INITARG VAL-DESIGNATORs.  You can use :INITARG VAL-DESIGNATORs
only with :CLASS-form.  Class form may be final (at end of rule right
side) action form only.

:DO evaluates form with variables who's names are symbols in :VAR
VAL-DESIGNATORs bound in lexical context with values of semantic
values of corresponding RULE-EXP.  You can use :VAR VAL-DESIGNATORs
only with :DO-form.  (:DO form is like PROGN in usual Lisp programs).

Rules can be more complex than list of terminals/nonterminals: it can
contain repetition operators like +, *, :LIST and :MAYBE for optional
items.

Rule expression (CL:* RULE-EXP) returns list of RULE-EXP as semantic
value.  It matches 0 or more repetitions of RULE-EXP.

Rule expression (CL:+ RULE-EXP) is similar to CL:*, but matches 1 or
more repetitions of RULE EXP.

(:MAYBE RULE-EXP) defines optional elements.  If RULE-EXP doesn't
match, NIL is returned as semantic value, otherwise semantic value of
RULE-EXP is used.

(:LIST RULE-EXP1 RULE-EXP2) finds non-empty list of RULE-EXP1
delimited by RULE-EXP2.  Semantic values aof RULE-EXP1 and RULE-EXP2
are in same list.  For example:

  (SEQ -> (:LIST OPERATOR SEMICOLON))

is equivalent to:

  (SEQ ->
       OPERATOR)
  (SEQ ->
       OPERATOR SEMICOLON OPERATOR)
  (SEQ ->
       OPERATOR SEMICOLON OPERATOR SEMICOLON OPERATOR)
  ... #| and so on |#

Note that

  (SEQ2 -> (:LIST OPERATOR SEMICOLON) SEMICOLON)

equals to

  (SEQ2 ->
       OPERATOR SEMICOLON)
  (SEQ2 ->
       OPERATOR SEMICOLON OPERATOR SEMICOLON)
  (SEQ2 ->
       OPERATOR SEMICOLON OPERATOR SEMICOLON OPERATOR SEMICOLON)
  ... #| and so on |#

Such expressions must be used with caution: they can introduce
conflicts.

Keywords:

* :RESERVED-TERMINALS
  List of terminals that are reserved, i.e. are not used by current
  grammar, but defined by language.  If there are some terminals that
  are not declared reserved but unused, warning is signaled.  If some
  reserved terminals are used, another warning is signaled.

* :PREC-INFO

Precedence info.  Argument is list of prec-lists.  Each prec-list
start with one of keywords: :LEFT, :RIGHT or :NONE for
left-associative, right-associative or non-associative operator.
Rest of elements are terminals and nonterminals.

Order of prec-lists defines their priority: tokens with least priority
first.

* :TYPE

Parser type: :LL, :LALR (default), :LR (aka :LR1), :LR0 and :SLR.

* :LEXER-OPTIONS

List of options.  Currently only one option is available: :CONTEXT.
So, valid value is either empty list (default) or '(:CONTEXT).  See
file LEXER for more info.

;; LocalWords:  LALR