Skip to content

Documentation for grammar.py

titan.common.grammar

TitanPythonGrammar

Bases: NamedTuple

Grammar for parsing Python.

Warning

This has been deprecated in favour for Python's AST module. This grammar should not be used at all.

Source code in titan/common/grammar.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
class TitanPythonGrammar(NamedTuple):
    """ Grammar for parsing Python.

        Warning:
            This has been deprecated in favour for Python's AST module. This grammar should not be used at all.
    """

    # keywords
    keyword_def = pp.Keyword("def")
    keyword_return = pp.Keyword("return")
    keyword_None = pp.Keyword("None")

    function_name = pp.pyparsing_common.identifier
    variable_name = pp.pyparsing_common.identifier

    # symbols
    l_br, r_br = map(pp.Literal, "()")
    l_cbr, r_cbr = map(pp.Literal, "{}")
    colon = pp.Literal(":")
    semicolon = pp.Literal(";")
    return_arrow = pp.Literal("->")

    number = pp.pyparsing_common.number

    type = pp.one_of(["int", "float", "bool"])

    parameter_with_type_hint = pp.Group(variable_name.set_results_name("parameter") + colon.suppress() + type.set_results_name("type"))
    function_parameter_list_with_type_hint = pp.delimited_list(parameter_with_type_hint) | pp.empty

    function_parameter_list = pp.delimited_list(variable_name) | pp.empty
    function_return_list = pp.Group(pp.delimited_list(variable_name | number | keyword_None))
    function_call = function_name + l_br + function_parameter_list + r_br
    # function_definition = keyword_def.suppress() + function_name.set_results_name("function_name") + l_br.suppress() + function_parameter_list.set_results_name("function_param_list") + r_br.suppress() + colon.suppress()
    function_definition = keyword_def.suppress() + function_name.set_results_name("function_name") + l_br.suppress() + function_parameter_list_with_type_hint.set_results_name("function_param_list") + r_br.suppress() + return_arrow.suppress() + (type | keyword_None).set_results_name("function_return_type") + colon.suppress()

    # TODO: this doesn't like parsing "a + b - 3" or anything that isn't nicely seperated by brackets
    #       - tried the github ver down below but it also has the same issue, the operators.py file needs to be looked at
    # precendece reference for the comparison operators https://en.cppreference.com/w/c/language/operator_precedence
    # TODO: perhaps this should have its name changed, it is no longer only handling only arithmetic, but also comparison and bitwise operators
    arithmetic_expression = pp.infix_notation(variable_name | number, [
        ("-", 1, pp.OpAssoc.RIGHT, o.UnaryOp),
        ("~", 1, pp.OpAssoc.RIGHT, o.UnaryOp),
        (pp.one_of("* /"), 2, pp.OpAssoc.LEFT, o.BinaryOp),
        (pp.one_of("+ -"), 2, pp.OpAssoc.LEFT, o.BinaryOp),
        (pp.one_of("& | ^"), 2, pp.OpAssoc.LEFT, o.BinaryOp),
        (pp.one_of("< <= >= > == !="), 2, pp.OpAssoc.LEFT, o.BinaryOp),
        (pp.one_of("<< >>"), 2, pp.OpAssoc.LEFT, o.BinaryOp)
    ])

    # TODO: should these be separate or merged with the arithmetic_expression object
    bitwise_expression = pp.infix_notation(variable_name | number, [
        ("~", 1, pp.OpAssoc.RIGHT, o.UnaryOp),
        (pp.one_of("& | ^"), 2, pp.OpAssoc.LEFT, o.BinaryOp)
    ])


    comparison_expression = pp.infix_notation(variable_name | number | arithmetic_expression, [
        (pp.one_of("< <= >= > == !="), 2, pp.OpAssoc.LEFT, o.BinaryOp)
    ])


    # combo_expression = arithmetic_expression ^ bitwise_expression ^ comparison_expression

    combo_expression = number ^ variable_name ^ arithmetic_expression

    conditional_ternary_expr = (combo_expression + pp.Literal("if").suppress() + comparison_expression + pp.Literal("else").suppress() + combo_expression).set_parse_action(o.TernaryCondOp)


    # https://github.com/pyparsing/pyparsing/blob/master/examples/simpleArith.py
    # arithmetic_expression = pp.infix_notation(variable_name | number, [
    #     (pp.one_of("+ -"), 1, pp.OpAssoc.RIGHT, o.UnaryOp),
    #     (pp.one_of("* /"), 2, pp.OpAssoc.LEFT, o.BinaryOp),
    #     (pp.one_of("+ -"), 2, pp.OpAssoc.LEFT, o.BinaryOp)
    # ])

    assignment = (variable_name + "=" + (combo_expression ^ conditional_ternary_expr ^ function_call)).set_results_name("assignment")
    # assignment = (variable_name + "=" + (combo_expression | function_call)).set_results_name("assignment")

    # an optional ";" was added to the end of the statement and function return grammars, this is so that it can still match
    # when doing the preprocessing step, and when it comes to parsing the file itself
    # TODO: this might cause issues, maybe split into two seperate variables?
    statement = (pp.Group(assignment) | pp.Group(function_call)) + pp.Opt(semicolon.suppress())

    function_body = pp.Group(pp.ZeroOrMore(statement)).set_results_name("function_statements") + pp.Optional(keyword_return.suppress()  + function_return_list.set_results_name("function_returns") + pp.Opt(semicolon.suppress()))

    module = pp.ZeroOrMore(
        pp.Group(
            function_definition + l_cbr.suppress() + function_body + r_cbr.suppress()
            )
    )

TitanSPIRVGrammar

Bases: NamedTuple

Grammar for parsing SPIR-V assembly.

Requires pyparsing to function.

Source code in titan/common/grammar.py
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
class TitanSPIRVGrammar(NamedTuple):
    """ Grammar for parsing SPIR-V assembly.

        Requires ``pyparsing`` to function.
    """

    pp.ParserElement.set_default_whitespace_chars(" \t")
    nl = pp.Literal("\n")
    eq = pp.Literal("=").suppress()
    op = pp.Literal("Op").suppress()

    id = pp.Combine(pp.Literal("%") + pp.pyparsing_common.identifier).set_results_name("id")
    literal_string = pp.quoted_string # https://pyparsing-docs.readthedocs.io/en/latest/HowToUsePyparsing.html?highlight=string#common-string-and-token-constants

    opcode = op + pp.Word(pp.alphanums).set_results_name("opcode")

    opcode_args = pp.Group(pp.delimited_list(
        pp.ZeroOrMore(id | literal_string | pp.Word(pp.alphanums) | pp.pyparsing_common.number),
        delim=" ",
        allow_trailing_delim=False
    )).set_results_name("opcode_args")


    operation = opcode + pp.Opt(opcode_args) + nl.suppress()
    assignment = id + eq + operation

    line = pp.Group(operation | assignment)

    spirv_body = pp.ZeroOrMore(
        line
    )

Last update: 2023-12-24