Tracing and debugging

When the parser doesn't work as expected there are several options. First, you can use pglr command to visualize LR PDA automata and GLR trace. The same command can also be used to print detailed information on the grammar, LR states and conflicts.

Printing detailed debug information on grammar can be also achieved by putting the grammar in the debug mode:

grammar = Grammar.from_file(file_name, debug=True)

For example, calc grammar from the quick intro would give the following output:

*** GRAMMAR ***
Terminals:
EMPTY - * ^ + STOP ( \d+(\.\d+)? number / EOF )
NonTerminals:
E S'
Productions:
0: S' = E STOP
1: E = E + E
2: E = E - E
3: E = E * E
4: E = E / E
5: E = E ^ E
6: E = ( E )
7: E = number

During grammar object construction, grammar file is parsed using the parglare itself and the grammar object for the new language is constructed. If you want to see the debug output of this process set the parse_debug parameter to True:

grammar = Grammar.from_file(file_name, parse_debug=True)

If you are using custom recognizers or would like to see the result of each action in debug output then you should put the parser in the debug mode from the code.

To put the parser in the debug mode do:

parser = Parser(grammar, debug=True)

To debug layout grammar do:

parser = Parser(grammar, debug_layout=True)

GLRParser can produce visual trace. To enable visual tracing set debug and debug_trace to True:

parser = GLRParser(grammar, debug=True, debug_trace=True)

Debug output and visual trace can be generated using pglr command. For example, parsing expression 1 + 2 * 3 with GLRParser in debug mode will produce the following output (this output is generated by pglr -i trace calc.pg "1 + 2 * 3"):

Grammar OK.


*** STATES ***

State 0
        0: S' = . E STOP   {}
        1: E = . E + E   {STOP, ^, ), /, *, -, +}
        2: E = . E - E   {STOP, ^, ), /, *, -, +}
        3: E = . E * E   {STOP, ^, ), /, *, -, +}
        4: E = . E / E   {STOP, ^, ), /, *, -, +}
        5: E = . E ^ E   {STOP, ^, ), /, *, -, +}
        6: E = . ( E )   {STOP, ^, ), /, *, -, +}
        7: E = . number   {STOP, ^, ), /, *, -, +}



        GOTO:
        E->1

        ACTIONS:
        (->SHIFT:2, number->SHIFT:3

....
....

*** PARSING STARTED

        Skipping whitespaces: ''
        New position: (1, 0)

**REDUCING HEADS
Active heads 1: [state=0:S', pos=0, endpos=0, empty=[False,True], parents=0, trees=1]
Number of trees = 1

Reducing head: state=0:S', pos=0, endpos=0, empty=[False,True], parents=0, trees=1
        Skipping whitespaces: ''
        New position: (1, 0)
        Position: (1, 0)
        Context: *1 + 2 * 3
        Symbols expected: ['(', 'number']
        Token(s) ahead: [<number(1)>]

        New head for shifting: state=0:S', pos=0, endpos=0, token
              ahead=<number(1)>, empty=[False,True], parents=0, trees=1.

        No more reductions for this head and lookahead token <number(1)>.

**SHIFTING HEADS
Active heads 1: [state=0:S', pos=0, endpos=0, token ahead=<number(1)>,
     empty=[False,True], parents=0, trees=1]
Number of trees = 1

Shifting head: state=0:S', pos=0, endpos=0, token ahead=<number(1)>,
     empty=[False,True], parents=0, trees=1
        Position: (1, 0)
        Context: *1 + 2 * 3
        Token(s) ahead: <number(1)>

        Shift:3 "1" at position (1, 0)
        Action result = type:<class 'parglare.parser.NodeTerm'>
            value:<Term(start=0, end=1, sym=number, val="1")>
        New shifted head state=3:number, pos=0, endpos=1, empty=[False,True],
            parents=0, trees=0.
        Creating link   from head state=3:number, pos=0, endpos=1,
                            empty=[False,False], parents=1, trees=1
                  to head   state=0:S', pos=0, endpos=0, token
                            ahead=<number(1)>, empty=[False,True],
                            parents=0, trees=1
 ....
 ....

 Reducing head: state=1:E, pos=0, endpos=9, token ahead=<STOP()>,
       empty=[False,False], parents=1, trees=1
    Position: (1, 9)
    Context: 1 + 2 * 3*
    Symbols expected: ['STOP']
    Token(s) ahead: <STOP()>

    *** SUCCESS!!!!
  *** 1 sucessful parse(s).
  Generated file parglare_trace.dot.

In addition, a visualization of GLR trace is produced as a Graphviz dot file.