- python-ast.grm.sx: This is a simplified Python grammar. It is actually the only file I'll be editing, as I must add derp reductions to each of the rules.
- pyparse.rkt: This file converts the output from my lexer to tokens that derp can parse.
- derivative-parsers.rkt: This file is derp. It applies the reductions in python-ast.grm.sx to the rules and produces an abstract syntax tree.
- Derp has a number of recognized reductions. The most basis one is (red L f) where L is a language and f is a process. This reduction applies the process to each parse of the language.
<example>
- (--> L f) is equivalent to (red L f).
- (car L) is equivalent to (red L (λ (t) (car t))). That is, the process (f) in this case is an anonymous (lambda) function that applies car to each parse of the language. In Racket, car returns the first element in a pair (t).
<example>
- (@--> L f) is equivalent to (red L (λ (t) (apply f t))). In the following example:
(@--> (seq! `SYMBOL "," `example) cons)
- `SYMBOL is a pattern to be matched
- `example is a rule
- cons is a Racket function that adds an item to the beginning of a list
- L = (seq! `SYMBOL "," `example)
- f = cons
Each sequence that matches the pattern (`SYMBOL "," `example) is cons-ed onto a list.
- (>--> L c ...) is equivalent to (red L (λ (t) (match t c ...))).
<example>
- ($--> L e ...) parses into the value of (begin e ...), with $$ bound to the match of L and ($ n) returning the nth member of $$. In the following example:
($--> SYMBOL (list $$))Reductions in Action
- SYMBOL is a language
- list is a Racket function that returns a list containing its arguments
- $$ is essentially "foreach"
- L = SYMBOL
- e = (list $$)
Each matched symbol is added to a list, which is then returned. Replacing $$ with $3 would just return a list containing the third match.
The rule with the least number of dependencies in python-ast.grm.sx is atom, which looks like:
Applying reductions to the bottom 7 languages (starting with NAME), we get something that looks like:(atom (or (seq "(" (opt tuple_or_test) ")") (seq "[" (opt testlist) "]")(seq "{" (opt dictorsetmaker) "}")NAMENUMBER(rep+ STRING)"...""None""True""False"))
That's all the work I've done so far. Next I'm going to continue with atom, applying reductions to the first 3 languages. And after that I'll work on the other rules.(atom (or (seq "(" (opt tuple_or_test) ")") (seq "[" (opt testlist) "]")(seq "{" (opt dictorsetmaker) "}")(>--> NAME [a a])(>--> NUMBER [a a])(>--> (rep+ STRING) [a a])($--> "..." 'Ellipsis)(>--> "None" [a a])(>--> "True" [a a])(>--> "False" [a a])))