-
Notifications
You must be signed in to change notification settings - Fork 35
/
kparser.rb
62 lines (45 loc) · 1.63 KB
/
kparser.rb
1
2
3
4
5
6
7
8
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
# Author: Chris Wailes <chris.wailes@gmail.com>
# Project: Ruby Language Toolkit
# Date: 2011/05/09
# Description: This file defines a simple parser for the Kazoo language.
# RLTK Files
require 'rltk/parser'
# Tutorial Files
require './kast'
module Kazoo
class Parser < RLTK::Parser
left :IN
left :LT, :ELSE
left :PLUS, :SUB
left :MUL, :DIV
production(:input, 'statement SEMI') { |s, _| s }
production(:statement) do
clause('e') { |e| e }
clause('ex') { |e| e }
clause('p') { |p| p }
clause('f') { |f| f }
end
production(:e) do
clause('LPAREN e RPAREN') { |_, e, _| e }
clause('NUMBER') { |n| Number.new(n) }
clause('IDENT') { |i| Variable.new(i) }
clause('e PLUS e') { |e0, _, e1| Add.new(e0, e1) }
clause('e SUB e') { |e0, _, e1| Sub.new(e0, e1) }
clause('e MUL e') { |e0, _, e1| Mul.new(e0, e1) }
clause('e DIV e') { |e0, _, e1| Div.new(e0, e1) }
clause('e LT e') { |e0, _, e1| LT.new(e0, e1) }
clause('IDENT LPAREN args RPAREN') { |i, _, args, _| Call.new(i, args) }
clause('FOR IDENT ASSIGN e COMMA e COMMA e IN e') do |_, i, _, e0, _, e1, _, e2, _, e3|
For.new(i, e0, e1, e2, e3)
end
clause('IF e THEN e ELSE e') { |_, e0, _, e1, _, e2| If.new(e0, e1, e2) }
end
empty_list(:args, :e, :COMMA)
production(:ex, 'EXTERN p_body') { |_, p| p }
production(:p, 'DEF p_body') { |_, p| p }
production(:f, 'p e') { |p, e| Function.new(p, e) }
production(:p_body, 'IDENT LPAREN arg_defs RPAREN') { |name, _, arg_names, _| Prototype.new(name, arg_names) }
empty_list(:arg_defs, :IDENT, :COMMA)
finalize({:use => 'kparser.tbl'})
end
end