olavo_calculator 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/README.md +36 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/olavo_calculator +5 -0
- data/lib/olavo_calculator/cli.rb +13 -0
- data/lib/olavo_calculator/lexer.rb +70 -0
- data/lib/olavo_calculator/parser.rb +74 -0
- data/lib/olavo_calculator/token.rb +8 -0
- data/lib/olavo_calculator/version.rb +3 -0
- data/lib/olavo_calculator.rb +11 -0
- data/olavo_calculator +5 -0
- data/olavo_calculator.gemspec +36 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c4ca2d1111c63e314d0bd9770d27d09d5594cdd9
|
4
|
+
data.tar.gz: d77214aecffde3b00a761bb9242a19107aacb9fc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ba877e24f22e89f9c6a00c4c850f2fbd5c77597ac064c89a964ae622db3e0cf74e940c002459083ab4a7b30055f9c10101a7101799a8b6616768c1b7756e04bc
|
7
|
+
data.tar.gz: dfa4f7ebdeb255b6abc16d34040813c11c00ed3e86f2b6c4c6fdb906962d3680a91b7b46da511234d1fa00ae0645c4cafff70f702982659646dd40740640d69a
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# OlavoCalculator
|
2
|
+
|
3
|
+
This is a simple gem that allow users to execute a string as a mathematical expression.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'olavo_calculator'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install olavo_calculator
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
OlavoCalculator.solve('6*5*4*3*2*1')
|
25
|
+
```
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
+
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/hammurabi13th/olavo-calculator
|
36
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "olavo_calculator"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'olavo_calculator'
|
3
|
+
|
4
|
+
module OlavoCalculator
|
5
|
+
class CLI < Thor
|
6
|
+
desc("solve EXPRESSION", "Solves the given EXPRESSION and returns the result")
|
7
|
+
def solve expression
|
8
|
+
puts OlavoCalculator.solve expression
|
9
|
+
end
|
10
|
+
|
11
|
+
default_task :solve
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class OlavoCalculator::Lexer
|
2
|
+
|
3
|
+
TOKENS = {
|
4
|
+
:'[' => :open_bracket,
|
5
|
+
:'(' => :open_parenthesis,
|
6
|
+
:'{' => :open_key,
|
7
|
+
:']' => :close_bracket,
|
8
|
+
:')' => :close_parenthesis,
|
9
|
+
:'}' => :close_key,
|
10
|
+
:'+' => :plus,
|
11
|
+
:'-' => :minus,
|
12
|
+
:'*' => :mult,
|
13
|
+
:'/' => :div
|
14
|
+
}
|
15
|
+
|
16
|
+
def self.tokenize string
|
17
|
+
tokens = []
|
18
|
+
last_token = nil
|
19
|
+
i = 0
|
20
|
+
|
21
|
+
while i < string.length do
|
22
|
+
i = detect_token(string, i, tokens)
|
23
|
+
end
|
24
|
+
|
25
|
+
tokens
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.detect_token string, index, tokens
|
29
|
+
current = string[index]
|
30
|
+
|
31
|
+
if current =~ /\s/
|
32
|
+
return index + 1
|
33
|
+
end
|
34
|
+
|
35
|
+
if current =~ /\d/ || (current =~ /-/ && (index + 1) < string.length && string[index + 1] =~ /\d/)
|
36
|
+
return detect_number string, index, tokens
|
37
|
+
end
|
38
|
+
|
39
|
+
if TOKENS.keys.include? current.to_sym
|
40
|
+
tokens << OlavoCalculator::Token.new(TOKENS[current.to_sym], current.to_sym)
|
41
|
+
return index + 1
|
42
|
+
end
|
43
|
+
|
44
|
+
raise "Syntax Error"
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.detect_number string, index, tokens
|
48
|
+
number = string[index]
|
49
|
+
|
50
|
+
index = get_number number, string, index + 1
|
51
|
+
|
52
|
+
if index + 1 < string.length && string[index] =~ /\./ && string[index + 1] =~ /\d/
|
53
|
+
number << '.'
|
54
|
+
index = get_number number, string, index + 1
|
55
|
+
end
|
56
|
+
|
57
|
+
tokens << OlavoCalculator::Token.new(:number, number.to_f)
|
58
|
+
|
59
|
+
index
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.get_number number, string, index
|
63
|
+
while index < string.length && string[index] =~ /\d/ do
|
64
|
+
number << string[index]
|
65
|
+
index += 1
|
66
|
+
end
|
67
|
+
|
68
|
+
index
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class OlavoCalculator::Parser
|
2
|
+
|
3
|
+
PRIORITY_SEMANTICS = {
|
4
|
+
:open_parenthesis => :close_parenthesis,
|
5
|
+
:open_bracket => :close_bracket,
|
6
|
+
:open_key => :close_key
|
7
|
+
}
|
8
|
+
|
9
|
+
def self.parse token_array
|
10
|
+
detect_expression token_array
|
11
|
+
end
|
12
|
+
|
13
|
+
# expressões podem ser da forma: priority (PLUS|MINUS expr)*, term
|
14
|
+
def self.detect_expression token_array
|
15
|
+
raise "Unexpected Ending" if token_array.empty?
|
16
|
+
value = detect_priority token_array
|
17
|
+
|
18
|
+
return value if token_array.empty?
|
19
|
+
|
20
|
+
next_token = token_array.shift
|
21
|
+
|
22
|
+
while next_token && [:plus, :minus].include?(next_token.type) do
|
23
|
+
value += detect_term(token_array) if next_token.type == :plus
|
24
|
+
value -= detect_term(token_array) if next_token.type == :minus
|
25
|
+
next_token = token_array.shift
|
26
|
+
end
|
27
|
+
|
28
|
+
token_array.unshift next_token
|
29
|
+
token_array.unshift OlavoCalculator::Token.new(:number, value)
|
30
|
+
|
31
|
+
detect_term token_array
|
32
|
+
end
|
33
|
+
|
34
|
+
# prioridades podem ser da forma: (expr), [expr], {expr}, term
|
35
|
+
def self.detect_priority token_array
|
36
|
+
raise "Unexpected Ending" if token_array.empty?
|
37
|
+
|
38
|
+
if PRIORITY_SEMANTICS.key? token_array[0].type
|
39
|
+
priority = token_array.shift
|
40
|
+
value = detect_expression token_array
|
41
|
+
raise "Semantic Error" unless token_array.shift.type == PRIORITY_SEMANTICS[priority.type]
|
42
|
+
return value
|
43
|
+
end
|
44
|
+
|
45
|
+
detect_term token_array
|
46
|
+
end
|
47
|
+
|
48
|
+
# termos podem ser da forma: factor ((MULT|DIV) factor)*
|
49
|
+
def self.detect_term token_array
|
50
|
+
raise "Unexpected Ending" if token_array.empty?
|
51
|
+
value = detect_factor token_array
|
52
|
+
|
53
|
+
return value if token_array.empty?
|
54
|
+
|
55
|
+
next_token = token_array.shift
|
56
|
+
|
57
|
+
while next_token && [:mult, :div].include?(next_token.type) do
|
58
|
+
value *= detect_factor(token_array) if next_token.type == :mult
|
59
|
+
value /= detect_factor(token_array) if next_token.type == :div
|
60
|
+
next_token = token_array.shift
|
61
|
+
end
|
62
|
+
|
63
|
+
token_array.unshift next_token unless next_token.nil?
|
64
|
+
|
65
|
+
value
|
66
|
+
end
|
67
|
+
|
68
|
+
# fatores podem ser da forma: NUMBER, priority
|
69
|
+
def self.detect_factor token_array
|
70
|
+
raise "Unexpected Ending" if token_array.empty?
|
71
|
+
return token_array.shift.value if token_array[0].type == :number
|
72
|
+
detect_priority token_array
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "olavo_calculator/version"
|
2
|
+
require "olavo_calculator/token"
|
3
|
+
require "olavo_calculator/lexer"
|
4
|
+
require "olavo_calculator/parser"
|
5
|
+
|
6
|
+
module OlavoCalculator
|
7
|
+
def self.solve string
|
8
|
+
token_array = Lexer.tokenize string
|
9
|
+
Parser.parse token_array
|
10
|
+
end
|
11
|
+
end
|
data/olavo_calculator
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'olavo_calculator/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "olavo_calculator"
|
8
|
+
spec.version = OlavoCalculator::VERSION
|
9
|
+
spec.authors = ["Carlos Cardoso Dias"]
|
10
|
+
spec.email = ["ccd.leron@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Uma simples gem que permite a resolução de uma expressão matemática a partir de uma string}
|
13
|
+
spec.homepage = "https://github.com/hammurabi13th/olavo-calculator"
|
14
|
+
|
15
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
16
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
17
|
+
if spec.respond_to?(:metadata)
|
18
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
19
|
+
else
|
20
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
21
|
+
"public gem pushes."
|
22
|
+
end
|
23
|
+
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
25
|
+
f.match(%r{^(test|spec|features)/})
|
26
|
+
end
|
27
|
+
spec.bindir = "exe"
|
28
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ["lib"]
|
30
|
+
|
31
|
+
spec.add_dependency "thor", "~> 0.19.4"
|
32
|
+
|
33
|
+
spec.add_development_dependency "bundler", "~> 1.13"
|
34
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
35
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: olavo_calculator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Carlos Cardoso Dias
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.19.4
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.19.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.13'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.13'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- ccd.leron@gmail.com
|
72
|
+
executables:
|
73
|
+
- olavo_calculator
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- ".rspec"
|
79
|
+
- ".travis.yml"
|
80
|
+
- Gemfile
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- bin/console
|
84
|
+
- bin/setup
|
85
|
+
- exe/olavo_calculator
|
86
|
+
- lib/olavo_calculator.rb
|
87
|
+
- lib/olavo_calculator/cli.rb
|
88
|
+
- lib/olavo_calculator/lexer.rb
|
89
|
+
- lib/olavo_calculator/parser.rb
|
90
|
+
- lib/olavo_calculator/token.rb
|
91
|
+
- lib/olavo_calculator/version.rb
|
92
|
+
- olavo_calculator
|
93
|
+
- olavo_calculator.gemspec
|
94
|
+
homepage: https://github.com/hammurabi13th/olavo-calculator
|
95
|
+
licenses: []
|
96
|
+
metadata:
|
97
|
+
allowed_push_host: https://rubygems.org
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 2.6.8
|
115
|
+
signing_key:
|
116
|
+
specification_version: 4
|
117
|
+
summary: Uma simples gem que permite a resolução de uma expressão matemática a partir
|
118
|
+
de uma string
|
119
|
+
test_files: []
|