aptk.actions - Parse Actions

Parse Actions are used to create an abstract syntax tree from your parse tree.

Parse Actions are expected to be attributes of the parse-actions object passed to Parser. This can be an object of a class derived from ParseActions, but can be also a module with a collection of functions.

Parse-Action Callables

A parse-action is called from parser with two parameters:

  • parser - current Parser object
  • lex - current Lexem object

Whatever the parse-action returns will be then written into the ast attribute of the Lexem object.

Connecting Parse-Actions to Rules

The parser calls a parse-action for each captured match object, which is represented by a Lexem object:

  • If there is defined a parse-action in the matching rule, it is called. In following rule there would be called parse-action “some_action”, if you captured something using <some-rule>:

    some-rule  some_action=  "some text"
    

    You can map shortcuts to actions:

    :parse-action-map
        "$" => other_action
    
    other-rule $= "other text"
    

    In this case there would be called parse-action “other_action”, if you captured “other text” with <other-rule>.

  • If there is not defined a parse-action in matching rule, it is tried to find following parse-actions if <my_rule> was matched:

    • my_rule
    • make_my_rule
    • got_my_rule
  • If no parse-action found, there is nothing done

Pairs

Setting an ast to a pair (name, result), where name is the rule’s name and result is result from parse-action, can be achieved with following syntax:

paired  action=>  <some> <rule>

If you append a “>” to your operator and you define an action for your rule the ast of the capture of <paired> will be the pair (paired, «result of action()»).

Example

>>> from aptk import *
>>> 
>>> class DashArithmeticGrammar(Grammar):
...    r"""Simple grammar for addition and substraction.
... 
...    dash_op    <= <sum> | <difference> | <number>
...    sum        := <number> "+" <dash_op>
...    difference := <number> "-" <dash_op>
...    """
>>> 
>>> class CalculatorActions(ParseActions):
...    r"""inherit number from ParseActions"""
...    def sum(self, p, lex):
...        return lex[0].ast + lex[1].ast
...    def difference(self, p, lex):
...        return lex[0].ast - lex[1].ast
>>> 
>>> ast("1 + 3 - 2", 
...     grammar = DashArithmeticGrammar, 
...     actions = CalculatorActions())
2