From: Michael D. Lowis Date: Wed, 31 Jul 2019 03:19:18 +0000 (-0400) Subject: implemented first pass at pratt parser X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=ab947228719dc3cca8077118f1f6fab045c33a9d;p=proto%2Fsclpl-rb.git implemented first pass at pratt parser --- diff --git a/compile.rb b/compile.rb index 99ff7ef..399c6f3 100755 --- a/compile.rb +++ b/compile.rb @@ -1,6 +1,7 @@ #!/usr/bin/env ruby require 'strscan' +require 'pp' module Type Void = "void" @@ -157,9 +158,13 @@ class Parser unary: 8, call: 9, primary: 10, + eof: 11 } - RULES = {} + RULES = { + "(" => { prefix: :grouping, infix: :func_call, level: :call }, + :int => { prefix: :constant, infix: nil, level: :none }, + } def initialize(path) @lex = Lexer.new(path) @@ -208,7 +213,7 @@ class Parser expect("=") value = expression() end - pp value + p "value", value end def declaration(syms) @@ -252,28 +257,45 @@ class Parser RULES[tok.type] end + def keepGoing(level) + rule = getRule(peek()) + (LEVELS[level] <= LEVELS[rule[:level]]) if rule + end + def parseLevel(level) -# advance() -# prefixRule = getRule(@prev)[:prefix] -# if not prefixRule then -# error("expected an expression") -# end -# send(prefixRule) -# while (level <= LEVELS[getRule(@curr)[:level]]) -# advance() -# infixRule = getRule(@prev)[:infix] -# send(infixRule) -# end + consume() + prefixRule = getRule(@prev)[:prefix] + if not prefixRule then + error("expected an expression") + end + ast = send(prefixRule) + while keepGoing(level) + consume() + infixRule = getRule(@prev)[:infix] + ast = send(infixRule, ast) + end + ast end def constant() - if (peek().type == :int) - AST::Value.new(Type::Int, consume().text.to_i) + if (@prev.type == :int) + AST::Value.new(Type::Int, @prev.text.to_i) else error("not a valid constant") end end + def grouping() + ast = expression() + expect(")") + ast + end + + def func_call(ast) + expect(")") + ast + end + def error(str) raise str end diff --git a/example.src b/example.src index c5b48c1..dd68e44 100644 --- a/example.src +++ b/example.src @@ -4,8 +4,8 @@ provides { fun main(args string[]) int } -let foo int = 42 +let foo int = (42) fun main(args string[]) int { - 42 + 42() }