Class: Randexp::Parser
- Inherits:
-
Object
- Object
- Randexp::Parser
- Defined in:
- lib/randexp/parser.rb
Class Method Summary collapse
- .balanced?(*args) ⇒ Boolean
- .intersection(lhs, rhs) ⇒ Object
- .literal(word) ⇒ Object
- .parse(source) ⇒ Object (also: [])
- .parse_quantified(source, multiplicity) ⇒ Object
- .quantify(lhs, sym) ⇒ Object
- .quantify_rhs(sexp, multiplicity) ⇒ Object
- .random(char) ⇒ Object
- .union(lhs, *rhs) ⇒ Object
Class Method Details
.balanced?(*args) ⇒ Boolean
50 51 52 |
# File 'lib/randexp/parser.rb', line 50 def self.balanced?(*args) args.all? {|s| s.count('(') == s.count(')')} end |
.intersection(lhs, rhs) ⇒ Object
81 82 83 84 85 86 87 |
# File 'lib/randexp/parser.rb', line 81 def self.intersection(lhs, rhs) if rhs.first == :intersection [:intersection, lhs] + rhs[1..-1] else [:intersection, lhs, rhs] end end |
.literal(word) ⇒ Object
93 94 95 |
# File 'lib/randexp/parser.rb', line 93 def self.literal(word) [:literal, word] end |
.parse(source) ⇒ Object Also known as: []
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 |
# File 'lib/randexp/parser.rb', line 3 def self.parse(source) case when source =~ /^(.*)(\*|\*\?|\+|\+\?|\?)$/ && balanced?($1, $2) parse_quantified($1, $2.to_sym) # ends with *, +, or ?: /(..)?/ when source =~ /^(.*)\{(\d+)\,(\d+)\}$/ && balanced?($1, $2) parse_quantified($1, ($2.to_i)..($3.to_i)) #ends with a range: /(..){..,..}/ when source =~ /^(.*)\{(\d+)\}$/ && balanced?($1, $2) parse_quantified($1, $2.to_i) #ends with a range: /..(..){..}/ when source =~ /^\((.*)\)\((.*)\)$/ && balanced?($1, $2) union(parse($1), parse($2)) #balanced union: /(..)(..)/ when source =~ /^(\(.*\))\|(\(.*\))$/ && balanced?($1, $2) intersection(parse($1), parse($2)) #balanced intersection: /(..)|(..)/ when source =~ /^(.*)\|(.*)$/ && balanced?($1, $2) intersection(parse($1), parse($2)) #implied intersection: /..|../ when source =~ /^(.*)\|\((\(.*\))\)$/ && balanced?($1, $2) intersection(parse($1), parse($2)) #unbalanced intersection: /(..)|((...))/ when source =~ /^(.+)(\(.*\))$/ && balanced?($1, $2) union(parse($1), parse($2)) #unbalanced union: /...(...)/ when source =~ /^\((.*)\)$/ && balanced?($1) union(parse($1)) #explicit group: /(..)/ when source =~ /^([^()]*)(\(.*\))$/ && balanced?($1, $2) union(parse($1), parse($2)) #implied group: /..(..)/ when source =~ /^(.*)\[\:(.*)\:\]$/ union(parse($1), random($2)) #custom random: /[:word:]/ when source =~ /^(.*)\\([wsdc])$/ union(parse($1), random($2)) #reserved random: /..\w/ when source =~ /^(.*)\\(.)$/ || source =~ /(.*)(.|\s)$/ union(parse($1), literal($2)) #end with literal or space: /... / else nil end end |
.parse_quantified(source, multiplicity) ⇒ Object
36 37 38 39 40 41 42 43 44 |
# File 'lib/randexp/parser.rb', line 36 def self.parse_quantified(source, multiplicity) case source when /^[^()]*$/ then quantify_rhs(parse(source), multiplicity) #implied union: /...+/ when /^(\(.*\))$/ then quantify(parse(source), multiplicity) #group: /(...)?/ when /^(.*\))$/ then quantify_rhs(parse(source), multiplicity) #implied union: /...(...)?/ when /^(.*[^)]+)$/ then quantify_rhs(parse(source), multiplicity) #implied union: /...(...)...?/ else quantify(parse(source), multiplicity) end end |
.quantify(lhs, sym) ⇒ Object
64 65 66 |
# File 'lib/randexp/parser.rb', line 64 def self.quantify(lhs, sym) [:quantify, lhs, sym] end |
.quantify_rhs(sexp, multiplicity) ⇒ Object
54 55 56 57 58 59 60 61 62 |
# File 'lib/randexp/parser.rb', line 54 def self.quantify_rhs(sexp, multiplicity) case sexp.first when :union rhs = sexp.pop sexp << quantify(rhs, multiplicity) else quantify(sexp, multiplicity) end end |
.random(char) ⇒ Object
89 90 91 |
# File 'lib/randexp/parser.rb', line 89 def self.random(char) [:random, char.to_sym] end |
.union(lhs, *rhs) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/randexp/parser.rb', line 68 def self.union(lhs, *rhs) if lhs.nil? union(*rhs) elsif rhs.empty? lhs elsif lhs.first == :union rhs.each {|s| lhs << s} lhs else [:union, lhs, *rhs] end end |