by Vadim Zaytsev & others

Engage! Engage!



Engage! (2019–2021) is an event-based parser generator. As far as I know, this is the only event-based parser generator in existence (please tell me if I'm wrong, would be glad to hear of similar projects), even though event-based parsers like SAX or RxParse are not really rarities. It was designed and developed as an experiment and published at the REBLS workshop at SPLASH 2019. The PDF of the paper is freely available, it contains a more detailed and precise description of the idea, some implementation details and empirical comparison of parsers. The code of Engage! got improved a bit further due to a successful research project of Frank Groeneveld.

Example spec (link)

namespace AB
types
    ABProgram;
    Decl;
    ClearStmt, ConverseStmt, HandlerStmt, IfStmt, MapStmt, OverlayStmt, PrintStmt, ReturnStmt <: Stmt;
    Integer, String, Decimal <: Type;
    Var, Lit                 <: Expr;
tokens
  ' ', '\r', '\n' :: skip
  ';', '(', ')' :: mark
  'dcl', 'enddcl', 'integer', 'char', 'dec', 'clear', 'converse', 'handler',
  'if', 'endif', 'map', 'to', 'overlay', 'print', 'return' :: word
  number :: Num
  string :: Id
handlers
    EOF                 -> push ABProgram(data,code)
                           while code := pop Stmt,
                                 data := pop Decl
    Num                 -> push Lit(this)
    Id                  -> push Var(this)
    'dcl'               -> lift DCL
    'enddcl'            -> drop DCL
    ';' upon DCL        -> push Decl(v,t)
                           where t := pop Type,
                                 v := pop Var
    'integer' upon DCL  -> push Integer
    'char'    upon DCL  -> push String(n)
                           where x := await (Lit upon BRACKET) with CHAR,
                                 n := tear x
    'dec'     upon DCL  -> push Decimal(n)
                           where x := await (Lit upon BRACKET) with DEC,
                                 n := tear x
    '(' upon CHAR       -> lift BRACKET
    '(' upon DEC        -> lift BRACKET
    '(' upon HANDLER    -> lift BRACKET
    ')'                 -> drop BRACKET
    'clear'             -> push ClearStmt(view)
                           where view := await Var
    'converse'          -> push ConverseStmt(win)
                           where win := await Var with CONVERSE
    'handler'           -> push HandlerStmt(obj,proc)
                           where obj  := await Var,
                                 proc := await (Var upon BRACKET) with HANDLER
    'if'                -> push IfStmt(cond,branch)
                           where cond   := await Expr with IF,
                                 branch := await* Stmt
    'endif'             -> trim Stmt*
    'map'               -> push MapStmt(source,target)
                           where source := await Expr with MAP,
                                 target := await Var with MAP
    'overlay'           -> push OverlayStmt(source,target)
                           where source := await Expr with OVERLAY,
                                 target := await Var with OVERLAY
    'print'             -> push PrintStmt(message)
                           where message := await Expr
    'return'            -> push ReturnStmt
		



The page is maintained by Dr. Vadim Zaytsev a.k.a. @grammarware. Last updated: April 2026.
HTML 5 CSS 3