Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Lex
- def initialize(rule)
- @rule = rule
- @buf = ""
- end
- attr_accessor :buf
- def get
- @rule.each do |rule, token, action|
- if @buf =~ rule
- @buf = $'
- return token, action.call($&)
- end
- end
- return nil,nil
- end
- end
- class Parse
- def initialize(rule)
- @rule = rule
- @tokens = ""
- @values = []
- end
- attr_accessor :tokens, :values
- def set(token, value)
- @tokens += token
- @values.push(value)
- end
- def parse
- @rule.each do |rule, to, action|
- if ind = (rule =~ @tokens)
- @tokens.sub!(rule, to)
- action.call(ind, @values)
- return true
- end
- end
- return false
- end
- def clear
- @tokens = ""
- @values = []
- end
- end
- lex_rule = [[/exit/, 'e', Proc.new{|val| exit}],
- [/^\(/, 'l', Proc.new{|val| val}],
- [/^\)/, 'r', Proc.new{|val| val}],
- [/^\d+/, 'N', Proc.new{|val| val.to_i}],
- [/^\+/, 'o', Proc.new{|val| '+'}],
- [/^\-/, 'o', Proc.new{|val| '-'}],
- [/^\*/, 'O', Proc.new{|val| '*'}],
- [/^\//, 'O', Proc.new{|val| '/'}],
- [/^\s+/, 's', Proc.new{|val| val}]]
- lex = Lex.new(lex_rule)
- parse_rule = [[/s/, '', Proc.new{|ind, values| values.delete_at(ind)}],
- [/NON/, 'N', Proc.new{|ind, values| operator(ind, values)}],
- [/([ol])NoN([or])/, '\1N\2', Proc.new{|ind, values| operator(ind+1, values)}],
- [/^NoN$/, 'N', Proc.new{|ind, values| operator(ind, values)}],
- [/^NoNo/, 'No', Proc.new{|ind, values| operator(ind, values)}],
- [/lNr/, 'N', Proc.new{|ind, values| values.delete_at(ind); values.delete_at(ind+1)}]]
- def operator(ind, values)
- val_1 = values[ind]
- op = values[ind+1]
- val_2 = values[ind+2]
- values.delete_at(ind)
- values.delete_at(ind)
- case op
- when '+'
- values[ind] = val_1 + val_2
- when '-'
- values[ind] = val_1 - val_2
- when '*'
- values[ind] = val_1 * val_2
- when '/'
- values[ind] = val_1 / val_2
- end
- end
- parser = Parse.new(parse_rule)
- while true
- print '> '
- lex.buf = gets.chomp
- t, v = lex.get
- while (t)
- parser.set(t, v)
- t, v = lex.get
- end
- while(parser.parse)
- p parser.tokens
- p parser.values
- end
- puts parser.values.pop
- parser.clear
- end
Add Comment
Please, Sign In to add comment