PLY is a parser generator for Python akin to lex and yacc for C. In PLY, tokens are specified using regular expressions and a context-free grammar is specified using a variation of EBNF. The function is used to automatically generate the scanner/parser; it returns an object containing a parsing function. As with yacc, it is up to the programmer to specify the actions to be performed during parsing to build an abstract-syntax representation (Section 9.5).
The following is the PLY analog of the lex and yacc specifications from Section 3.5 to generate a parser for the symbolic expression language:
The tokens for the symbolic expression language are defined on lines 11–31 and the shift-reduce pattern-action rules are defined on lines 35–48. Notice that the syntax of the pattern-action rules in PLY differs from that in yacc. In PLY, the pattern-action rules are supplied in the form of a function definition. The docstring string literal at the top of the function definition (i.e., the text between the two """) specifies the production rule, and the part after the closing """ indicates the action to be taken. The scanner and parser are invoked on lines 51 and 52, respectively. Strings are read from standard input (line 54) with the newline character removed (line 55) and passed to the parser (line 57). The string is then tokenized and parsed. If the string is a sentence, the parser.parse function returns True; otherwise, it returns False. The parser is generated and run as follows:
The following is a grammar in EBNF for the language Camille developed in Part III of this text:
The Camille language evolves throughout the course of Part III. This grammar is for a version of Camille used in Chapter 11. The following code is a PLY scanner specification for the tokens in the Camille language:
The following code is a PLY parser specification for the Camille language defined by this grammar:
Notice that the action part of each pattern-action rule is empty. Thus, this parser does not build an abstract-syntax tree. For a parser generator that builds an abstract-syntax tree (used later for interpretation in Chapters 10–11), see the listing at the beginning of Section 9.6.2.5 For the details of PLY, see https://www.dabeaz.com/ply/.
5. These specifications have been tested and run in PLY 3.11. The scanner and parser generated by PLY from these specifications have been tested and run in Python 3.8.5.
3.16.79.65