Created
November 8, 2022 18:32
-
-
Save gkthiruvathukal/3a24638cfe3dbff984594fe4a87a7266 to your computer and use it in GitHub Desktop.
Use Tatsu to get generic AST and create IR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import tatsu | |
import json | |
from pprint import pprint | |
GRAMMAR = """@@grammar::ZQUERY | |
start = expression $ ; | |
expression | |
= | |
| or_expr | |
| term | |
; | |
or_expr | |
= | |
left:expression op:'|' right:term | |
; | |
term | |
= | |
| and_expr | |
| factor | |
; | |
and_expr | |
= left:term op:and_op right:factor | |
; | |
and_op | |
= op:'&' | |
| op:'!' | |
; | |
not_expr | |
= left:term op:'!' right:factor | |
; | |
factor | |
= | |
| '(' @:expression ')' | |
| z_field | |
; | |
z_field | |
= field:literal ':' text:literal | |
; | |
literal | |
= word:/"(\s+|\w+)*"/ | |
| word:/\w+/ | |
; | |
""" | |
from collections import namedtuple | |
Field = namedtuple("Field", ["field","text"]) | |
OpNode = namedtuple("OpNode", ["op", "left", "right"]) | |
class Semantics(object): | |
def literal(self, ast): | |
return ast.word | |
def z_field(self, ast): | |
return Field(ast.field, ast.text) | |
def and_expr(self, ast): | |
return OpNode(ast.op, ast.left, ast.right) | |
def and_op(self, ast): | |
return ast.op | |
def or_expr(self, ast): | |
return OpNode(ast.op, ast.left, ast.right) | |
def go(): | |
parser = tatsu.compile(GRAMMAR) | |
#line = input("> ") | |
line = "subject:x & (title:urgent | title:whatever) | to:gkt" | |
# Semantics-free AST - parser can inject semantics (ZettelGeist shows how to do this) | |
ast = parser.parse(line) | |
print(ast) | |
ir = parser.parse(line, semantics=Semantics()) | |
print(ir) | |
# Dump JSON just to get pretty-prineted "tree" representation | |
#print(json.dumps(ast, indent=3)) | |
if __name__ == '__main__': | |
go() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output looks like this: