@@ -0,0 +1,1574 @@
+from scanner import scanner%0D%0Afrom token import Token%0D%0A%0D%0Aclass ParserError(Exception):%0D%0A    def __init__(self, token, *expected_tokens):%0D%0A        template = %22Received %7B%7D, expected %7B%7B%7B%7D%7D%7D%22%0D%0A        self.message = template.format(token, ', '.join(expected_tokens))%0D%0A%0D%0A    def __str__(self):%0D%0A        return self.message%0D%0A%0D%0A%0D%0Adef consume(tokcar, tokcdr, *expected_tokens):%0D%0A    %22%22%22Consume a given token, checking that it is valid. Returns the next%0D%0A    token, and the literal representation of the given token. Note that tokcdr%0D%0A    gets modified.%0D%0A    Example usage:%0D%0A        tokcar, _ = consume(tokcar, tokcdr, Token.ADD, Token.MUL)%22%22%22%0D%0A    if tokcar%5B0%5D not in expected_tokens:%0D%0A        raise ParserError(tokcar, *expected_tokens)%0D%0A    print(%22Consuming%22, tokcar)%0D%0A    return next(tokcdr), tokcar%5B1%5D%0D%0A%0D%0A%0D%0Adef parser(tokens):%0D%0A    statements = %5B%5D%0D%0A    for token in tokens:%0D%0A        statements.append(statement(token, tokens))%0D%0A%0D%0A%0D%0Adef statement(tokcar, tokcdr):%0D%0A    if tokcar%5B0%5D == Token.LET:%0D%0A        return let(tokcar, tokcdr)%0D%0A    else:%0D%0A        raise ParserError(tokcar%5B0%5D, Token.LET)%0D%0A%0D%0Adef let(tokcar, tokcdr):%0D%0A    tokcar, _ = consume(tokcar, tokcdr, Token.LET)%0D%0A    tokcar, var = consume(tokcar, tokcdr, Token.ID)%0D%0A    if tokcar == Token.LSBRA:%0D%0A        tokcar, _ = consume(tokcar, tokcdr, Token.LSBRA)%0D%0A        tokcar, size_tok = consume(tokcar, tokcdr, Token.NUM)%0D%0A        tokcar, _ = consume(tokcar, tokcdr, Token.RSBRA)%0D%0A        size = int(size_tok)%0D%0A    else:%0D%0A        size = 1%0D%0A%0D%0A%0D%0Awith open('parsetest.mc') as f:%0D%0A    parser(scanner(f.read(), Token.regexes))%0D%0A%0D%0A

Add ill-fated parser