expression_parser-master/0000755000175000017500000000000012121626135016303 5ustar avtobiffavtobiffexpression_parser-master/lib/0000755000175000017500000000000012121626135017051 5ustar avtobiffavtobiffexpression_parser-master/lib/expression_parser.rb0000644000175000017500000000043012121626135023146 0ustar avtobiffavtobiff# Taken from http://lukaszwrobel.pl/blog/math-parser-part-3-implementation require File.join(File.dirname(__FILE__),'expression_parser/token') require File.join(File.dirname(__FILE__),'expression_parser/lexer') require File.join(File.dirname(__FILE__),'expression_parser/parser') expression_parser-master/lib/expression_parser/0000755000175000017500000000000012121626135022624 5ustar avtobiffavtobiffexpression_parser-master/lib/expression_parser/version.rb0000644000175000017500000000013512121626135024635 0ustar avtobiffavtobiffmodule ExpressionParser VERSION = "0.9.1" unless defined?(::ExpressionParser::VERSION) end expression_parser-master/lib/expression_parser/parser.rb0000644000175000017500000000451612121626135024453 0ustar avtobiffavtobiff# Taken from http://lukaszwrobel.pl/blog/math-parser-part-3-implementation module ExpressionParser class Parser def parse(input) @lexer = Lexer.new(input) expression_value = expression token = @lexer.get_next_token if token.kind == Token::End expression_value else compare_expr(token,expression_value,expression) end end protected def compare_expr(token,expression_value,expression) case token.kind when Token::GThan expression_value > expression ? 1 : 0 when Token::LThan expression_value < expression ? 1 : 0 when Token::Equal expression_value == expression ? 1 : 0 when Token::NotEqual expression_value != expression ? 1 : 0 when Token::GThanE expression_value >= expression ? 1 : 0 when Token::LThanE expression_value <= expression ? 1 : 0 else raise 'End expected' end end def expression component1 = factor additive_operators = [Token::Plus, Token::Minus] token = @lexer.get_next_token while additive_operators.include?(token.kind) component2 = factor if token.kind == Token::Plus component1 += component2 else component1 -= component2 end token = @lexer.get_next_token end @lexer.revert component1 end def factor factor1 = number multiplicative_operators = [Token::Multiply, Token::Divide, Token::MOD] token = @lexer.get_next_token while multiplicative_operators.include?(token.kind) factor2 = number if token.kind == Token::Multiply factor1 *= factor2 elsif token.kind == Token::MOD factor1 %= factor2 else factor1 /= factor2 end token = @lexer.get_next_token end @lexer.revert factor1 end def number token = @lexer.get_next_token if token.kind == Token::LParen value = expression expected_rparen = @lexer.get_next_token if [Token::GThan,Token::LThan,Token::Equal,Token::NotEqual,Token::GThanE,Token::LThanE].include?(expected_rparen.kind) tmp = expression value = compare_expr(expected_rparen,value,tmp) expected_rparen = @lexer.get_next_token end expected_rparen raise "Unbalanced parenthesis" unless expected_rparen.kind == Token::RParen elsif token.kind == Token::Number value = token.value else raise 'Not a number' end value end end end expression_parser-master/lib/expression_parser/token.rb0000644000175000017500000000104312121626135024267 0ustar avtobiffavtobiff# Taken from http://lukaszwrobel.pl/blog/math-parser-part-3-implementation module ExpressionParser class Token Plus = 0 Minus = 1 Multiply = 2 Divide = 3 Number = 4 LParen = 5 RParen = 6 MOD = 7 GThan = 8 LThan = 9 Equal = 10 NotEqual = 11 GThanE = 12 LThanE = 13 End = 14 attr_accessor :kind attr_accessor :value def initialize @kind = nil @value = nil end def unknown? @kind.nil? end end end expression_parser-master/lib/expression_parser/lexer.rb0000644000175000017500000000305512121626135024273 0ustar avtobiffavtobiff# Taken from http://lukaszwrobel.pl/blog/math-parser-part-3-implementation module ExpressionParser class Lexer def initialize(input) @input = input @return_previous_token = false end def get_next_token if @return_previous_token @return_previous_token = false return @previous_token end token = Token.new @input.lstrip! case @input when /\A\+/ then token.kind = Token::Plus when /\A-/ then token.kind = Token::Minus when /\A\*/ then token.kind = Token::Multiply when /\Adiv/ then token.kind = Token::Divide when /\A\// then token.kind = Token::Divide when /\A\d+(\.\d+)?/ token.kind = Token::Number token.value = $&.to_f when /\A\(/ token.kind = Token::LParen when /\A\)/ token.kind = Token::RParen when '' token.kind = Token::End when /\Ae/ token.kind = Token::Number token.value = 2.718281828459 when /\Api/ token.kind = Token::Number token.value = 3.1415926535898 when /\Amod/ token.kind = Token::MOD when /\A!=/ token.kind = Token::NotEqual when /\A<>/ token.kind = Token::NotEqual when /\A>=/ token.kind = Token::GThanE when /\A>/ token.kind = Token::GThan when /\A<=/ token.kind = Token::LThanE when /\A1' do @parser.parse('2>1').should == 1 end it 'should return 0 for 1>2' do @parser.parse('1>2').should == 0 end it 'should return 1 for 2=2' do @parser.parse('2=2').should == 1 end it 'should return 1 for 1+1>=2' do @parser.parse('1+1>=2').should == 1 end it 'should return 1 for 3<=1+1' do @parser.parse('3<=1+1+1').should == 1 end it 'should return 2 for (2>1)+1' do @parser.parse('(2>1)+1').should == 2 end end expression_parser-master/Gemfile0000644000175000017500000000007012121626135017573 0ustar avtobiffavtobiff#source :rubygems source 'https://rubygems.org' gemspec expression_parser-master/Rakefile0000644000175000017500000000025612121626135017753 0ustar avtobiffavtobiffrequire 'rubygems' require 'rake' require 'rspec/core/rake_task' require 'bundler' Bundler::GemHelper.install_tasks RSpec::Core::RakeTask.new(:spec) task :default => :spec expression_parser-master/expression_parser.gemspec0000644000175000017500000000175112121626135023427 0ustar avtobiffavtobiff# -*- encoding: utf-8 -*- lib = File.expand_path('../lib/', __FILE__) $:.unshift lib unless $:.include?(lib) require 'expression_parser/version' spec = Gem::Specification.new do |s| s.name = "expression_parser" s.version = ExpressionParser::VERSION s.author = "David Ricciardi" s.email = "nricciar@gmail.com" s.homepage = "http://github.com/nricciar/expression_parser" s.platform = Gem::Platform::RUBY s.summary = "Math parser based on Lukasz Wrobel's blog post" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.require_path = "lib" s.description = File.read("README") s.has_rdoc = false s.extra_rdoc_files = ["README","MIT-LICENSE"] s.description = %q{expression parser} s.add_development_dependency 'test-unit' s.add_development_dependency 'rspec' s.add_development_dependency 'rake' s.add_development_dependency 'rdoc' s.add_development_dependency(RUBY_VERSION =~ /^1\.9/ ? "simplecov" : "rcov") end expression_parser-master/README0000644000175000017500000000043612121626135017166 0ustar avtobiffavtobiff# Taken from http://lukaszwrobel.pl/blog/math-parser-part-3-implementation require 'rubygems' require 'expression_parser' parser = ExpressionParser::Parser.new loop do begin print '>> ' puts parser.parse(gets) rescue RuntimeError puts 'Error occured: ' + $! end end expression_parser-master/MIT-LICENSE0000644000175000017500000000202712121626135017740 0ustar avtobiffavtobiffCopyright (c) 2009. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.