dabeaz / sly

Sly Lex Yacc
Other
816 stars 107 forks source link

Parser().parse(tokens) returns nonetype #74

Closed ArachnidAbby closed 2 years ago

ArachnidAbby commented 3 years ago

text_input

println(2-3);
println(6-9);

code

class Parser(sly.Parser):
    tokens = lexer.Lexer.tokens

    def __init__(self, module, builder, printf):
        self.module = module
        self.builder = builder
        self.printf = printf

    @_('PRINT paren SEMI_COLON')
    def func(self,p):
        if p[0]=="print":
            return Print(self.builder, self.module, self.printf, p[1])
        else:
            return Println(self.builder, self.module, self.printf, p[1])

    @_('OPEN_PAREN express CLOSE_PAREN')
    def paren(self, p):
        print(p)
        return parenth(p[1])

    @_('NUMBER')
    def express(self, p):
        return Number(self.builder, self.module, p[0])

    @_('express SUM express')
    def express(self,p):
        left = p[0]
        right = p[2]
        operator = p[1]
        return Sum(self.builder, self.module, left, right)

    @_('express SUB express')
    def express(self,p):
        left = p[0]
        right = p[2]
        operator = p[1]
        return Sub(self.builder, self.module, left, right)

    def get_parser(self):
        return self.pg.build()

context

This code does work when using a single println() statement but not when using multiple. it ends up returning a nonetype

jpsnyder commented 2 years ago

It looks like you are using func as the starting point since it is the first defined production. That production only allows for a single println() statement.

You need to create a new start production that accepts multiple statements. Something like this should work (untested):

@_("func { func }")
def start(self, p):
    return [p.func0, *p.func1]