lexeme 0.0.1 → 0.0.2
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.
- data/lib/lexeme.rb +21 -9
- data/lib/lexeme/core_extensions.rb +19 -0
- data/lib/lexeme/lexeme.rb +42 -7
- data/lib/lexeme/rule.rb +2 -2
- metadata +5 -4
data/lib/lexeme.rb
CHANGED
|
@@ -2,19 +2,31 @@ require 'lexeme/rule'
|
|
|
2
2
|
require 'lexeme/ruleset'
|
|
3
3
|
require 'lexeme/token'
|
|
4
4
|
require 'lexeme/lexeme'
|
|
5
|
+
require 'lexeme/core_extensions'
|
|
5
6
|
|
|
6
7
|
module Lexeme
|
|
7
|
-
VERSION = '0.0.
|
|
8
|
+
VERSION = '0.0.2'
|
|
9
|
+
|
|
10
|
+
def self.analyze(source = nil)
|
|
11
|
+
raise RuntimeError, 'Please use #define before calling #analyze.' unless @lexer
|
|
12
|
+
|
|
13
|
+
return @lexer.instance_eval(&Proc.new) if
|
|
14
|
+
block_given?
|
|
15
|
+
|
|
16
|
+
return @lexer.analyze(source) unless
|
|
17
|
+
source.nil?
|
|
8
18
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
19
|
+
raise ArgumentError, 'Invalid parameters. Expected string or block.'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.define(&block)
|
|
23
|
+
@lexer = Lexeme.new #unless @lexer
|
|
24
|
+
@lexer.instance_eval(&block)
|
|
25
|
+
|
|
26
|
+
@lexer
|
|
12
27
|
end
|
|
13
28
|
|
|
14
|
-
def self.
|
|
15
|
-
|
|
16
|
-
tokens.each { |t| yield t } if block_given?
|
|
17
|
-
|
|
18
|
-
tokens
|
|
29
|
+
def self.reset!
|
|
30
|
+
remove_instance_variable(:@lexer) if @lexer
|
|
19
31
|
end
|
|
20
32
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class ::String
|
|
2
|
+
def to_tokens
|
|
3
|
+
content = to_s
|
|
4
|
+
|
|
5
|
+
Lexeme.define do
|
|
6
|
+
token :STOP => /^\.$/
|
|
7
|
+
token :COMA => /^,$/
|
|
8
|
+
token :QUES => /^\?$/
|
|
9
|
+
token :EXCL => /^!$/
|
|
10
|
+
token :QUOT => /^"$/
|
|
11
|
+
token :APOS => /^'$/
|
|
12
|
+
token :WORD => /^[\w\-]+$/
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
Lexeme.analyze do
|
|
16
|
+
return from_string content
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/lexeme/lexeme.rb
CHANGED
|
@@ -2,20 +2,39 @@ module Lexeme
|
|
|
2
2
|
class Lexeme
|
|
3
3
|
attr_accessor :ruleset
|
|
4
4
|
|
|
5
|
-
def
|
|
5
|
+
def from_file(filepath = nil)
|
|
6
6
|
raise ArgumentError, 'Argument 1 must be a String' unless
|
|
7
|
-
|
|
7
|
+
filepath.instance_of? String
|
|
8
8
|
|
|
9
9
|
raise ArgumentError, 'Source not defined' if
|
|
10
|
-
|
|
10
|
+
filepath.empty?
|
|
11
11
|
|
|
12
12
|
raise RuntimeError, 'Source file not readable' unless
|
|
13
|
-
File.exists?(
|
|
13
|
+
File.exists?(filepath)
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
|
|
16
|
+
scan IO.read(filepath)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def from_string(source)
|
|
20
|
+
raise ArgumentError, 'Argument 1 must be a String' unless
|
|
21
|
+
source.instance_of? String
|
|
22
|
+
|
|
23
|
+
raise ArgumentError, 'Source not defined' if
|
|
24
|
+
source.empty?
|
|
17
25
|
|
|
18
|
-
|
|
26
|
+
scan source
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Used by the Lexeme.define method
|
|
30
|
+
def token(params)
|
|
31
|
+
@ruleset ||= Ruleset.new
|
|
32
|
+
|
|
33
|
+
name = params.keys.first || nil
|
|
34
|
+
regex = params.values.first || nil
|
|
35
|
+
@ruleset.rule(name, regex)
|
|
36
|
+
|
|
37
|
+
@ruleset
|
|
19
38
|
end
|
|
20
39
|
|
|
21
40
|
private
|
|
@@ -25,9 +44,21 @@ module Lexeme
|
|
|
25
44
|
current = ''
|
|
26
45
|
tokens = []
|
|
27
46
|
line = 1
|
|
47
|
+
string_state = false
|
|
28
48
|
|
|
29
49
|
input.each_char do |c|
|
|
30
50
|
line += 1 if c == "\n"
|
|
51
|
+
|
|
52
|
+
if c == "'" || c == '"'
|
|
53
|
+
previous << c
|
|
54
|
+
string_state ^= true
|
|
55
|
+
next
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if string_state
|
|
59
|
+
previous << c
|
|
60
|
+
next
|
|
61
|
+
end
|
|
31
62
|
|
|
32
63
|
if ignorable?(c)
|
|
33
64
|
unless previous.empty?
|
|
@@ -62,6 +93,10 @@ module Lexeme
|
|
|
62
93
|
|
|
63
94
|
previous = current.clone
|
|
64
95
|
end
|
|
96
|
+
|
|
97
|
+
unless previous.empty?
|
|
98
|
+
tokens << identify(previous)
|
|
99
|
+
end
|
|
65
100
|
|
|
66
101
|
tokens
|
|
67
102
|
end
|
data/lib/lexeme/rule.rb
CHANGED
|
@@ -3,8 +3,8 @@ module Lexeme
|
|
|
3
3
|
attr_reader :name, :regex
|
|
4
4
|
|
|
5
5
|
def initialize(name, regex)
|
|
6
|
-
raise ArgumentError, 'name must be a String' unless
|
|
7
|
-
name.nil? || name.is_a?(String)
|
|
6
|
+
raise ArgumentError, 'name must be a String or a Symbol' unless
|
|
7
|
+
name.nil? || name.is_a?(String) || name.is_a?(Symbol)
|
|
8
8
|
raise ArgumentError, 'regex must be a Regex' unless
|
|
9
9
|
regex.is_a? Regexp
|
|
10
10
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lexeme
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,10 +9,10 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2013-
|
|
12
|
+
date: 2013-07-11 00:00:00.000000000 Z
|
|
13
13
|
dependencies: []
|
|
14
|
-
description: A
|
|
15
|
-
email: vladimir.ivic@
|
|
14
|
+
description: A simple lexical analyzer written in Ruby
|
|
15
|
+
email: vladimir.ivic@icloud.com
|
|
16
16
|
executables: []
|
|
17
17
|
extensions: []
|
|
18
18
|
extra_rdoc_files: []
|
|
@@ -22,6 +22,7 @@ files:
|
|
|
22
22
|
- lib/lexeme/token.rb
|
|
23
23
|
- lib/lexeme/ruleset.rb
|
|
24
24
|
- lib/lexeme/rule.rb
|
|
25
|
+
- lib/lexeme/core_extensions.rb
|
|
25
26
|
homepage: http://rubygems.org/gems/lexeme
|
|
26
27
|
licenses: []
|
|
27
28
|
post_install_message:
|