# [prs_gen.h] LALR(1) Parser Generator

## contents

#include "prs_dfn.h"

The module [prs_gen] performs two main tasks.

1) A set of functions will be used to dynamically create a BNF-like context free grammar definition. ( reentrant )
It is possible to define multiple startsymbols and comment tokens.

2) The latter function create the corresponding parse table and nonterminal classes. The parse table is the input for the parse function.
This creation process is not reentrant. You must synchronize the access to the function within threads.

      The following rules define the abstract syntax. On this base the nonterminal
      classes are created.

      A) well-formed productions:
      1. let X :nil  :            <0 members>
      2. let X :cons : Y Z        <2 members: Y = member && Z = nonterminal>
      3. let X :ign#*: Y          <1 nonterminal>
      4. let X :name : X1 .. Xn   <n >= 0 && name =/= { ign#, nil, cons }>

      B) construction of the token/nonterminal classes:
      1. X <=> X                          reflexiv
      2. X <=> Y --> Y <=> X              symmetric
      3. X <=> Y && Y <=> Z --> X <=> Z   transitiv
      4. let X :ign1: Y   --> X <=> Y
      5. let X :cons: Y Z --> X <=> Z
      6. X <=> Y && let X :idx: X1 .. Xn && let Y :idy: Y1 .. Ym && idx = idy
         --> n = m && forall i, 1 <= i <= n: Type(Xi) = Type(Yi) && Xi <=> Yi,
                                             where Type(Z) = { token, nonterminal }
      7. all tokens are equivalent.

      C) token/nonterminal classes:
         [X] = { Y | Y <=> X }
         class representants:
         - tokens:       "Tok"
         - startsymbols: language name
         - nonterminals: less nonterminal name according the lexical order

      D) correctness:
      1. X <=> Y --> Type(X) = Type(Y), where Type(Z) = { token, nonterminal }
      2. let X^ :id: a && let X^ :id: b --> a <=> b
      3. let X^ :nil: a || let X^ :cons: b
         --> not exists P: P = let X^ :id: c && id =/= { ign1, nil, cons }
      [ 1,2: checked during construction ]

      E) abstract context free grammar:
         NT |--> NT^
         T  |--> T^ ( NT^ T^ are the class representants )

         for all "normal" productions there will be one interface function
         of type 'bool' which returns whether the argument term represents
         a production of this kind and in the positive case all required members.

## Types

PLR_Cfg | Abstract context free grammar type

## Grammar definition

    PLR_Cfg PLR_createCfg(c_string Language)
| creates a context free grammar definition named 'Language'
    int PLR_addTK(PLR_Cfg Cfg, c_string Token, int kind)
| adds token 'Token' of type 'kind' ( token or keyword, see [cfg_dfn] ) to definition 'Cfg'
    int PLR_addNT(PLR_Cfg Cfg, c_string NonTerm, c_bool catchError)
| adds nonterminal 'NonTerm' to definition 'Cfg' catchError --> use 'NonTerm' as reparse point
    void PLR_endSD(PLR_Cfg Cfg)
| symbol definition end; completes token and nonterminal definition
    int PLR_addSN(PLR_Cfg Cfg, c_string StartNt)
| adds startsymbol 'StartNt' to definition 'Cfg'
    int PLR_addST(PLR_Cfg Cfg, c_string SpecTk)
| marks 'SpecTk' as special comment token
    int PLR_addPR(PLR_Cfg Cfg, c_string PName, int Method, c_string NonTerm)
| adds production 'NonTerm'::'PName' with layout hint 'Method' ( default=0, see [prs_dfn] ) to definition 'Cfg'
    int PLR_addPT(PLR_Cfg Cfg, c_string Token, long sRow, long sCol)
| adds token 'Token' to current production of definition 'Cfg'; The symbol position 'sRow', 'sCol' is used as layout hint.
    int PLR_addPK(PLR_Cfg Cfg, c_string Keyword, long sRow, long sCol)
| adds keyword 'Keyword' to current production of definition 'Cfg'; The symbol position 'sRow', 'sCol' is used as layout hint.
    int PLR_addPN(PLR_Cfg Cfg, c_string NonTerm, long sRow, long sCol)
| adds nonterminal 'NonTerm' to current production of definition 'Cfg'; The symbol position 'sRow', 'sCol' is used as layout hint.
    void PLR_delCfg(PLR_Cfg Cfg)
| removes grammar definition 'Cfg'

## Parse table creation

    PLR_Tab PLR_createTab(PLR_Cfg Cfg, c_bool verbose, c_bool diagnose)
| creates the corresponding parse table for definition 'Cfg' 'verbose' --> entertainment 'diagnose' --> print conflict / result informations
    PLR_Tab PLR_createTab_ex
            (
              PLR_Cfg Cfg, void (*prMsg)(c_string msg), c_bool verbose, c_bool diagnose
            )
| like PLR_createTab; uses 'prMsg' as print function