Class: Parser
- Inherits:
-
Object
- Object
- Parser
- Defined in:
- lib/schaefer/parser.rb
Instance Method Summary collapse
- #convertLiterals(data) ⇒ Object
- #convertTokens(tokens) ⇒ Object
- #formStructure(tokens, offset = 0) ⇒ Object
- #isComma?(string) ⇒ Boolean
-
#isInteger?(string) ⇒ Boolean
return true if string is made of any number of numerals optionally preceded by a + or -.
-
#isMatch?(string, pattern) ⇒ Boolean
check if type is a match, returns false if no, true if yes.
-
#isString?(string) ⇒ Boolean
return true if string is text surrounded by quotes.
-
#isSymbol?(string) ⇒ Boolean
return true if string is anything other than parenthasees, quotes, or commas.
- #parse(string) ⇒ Object
-
#pullSLiterals(string) ⇒ Object
method used to remove all string literals, save them in an array, and replace them with a set string that will not interfere with parsing.
-
#replaceSLiterals(tokens, literals) ⇒ Object
method used to restore string literals in our tokens array now that we dont have to worry about special cases.
-
#tokenize(string) ⇒ Object
method used split program into tokens by adding spaces arround ‘(’s and calling string.split(‘ ’).
-
#toToken(data) ⇒ Object
Convert a set of nested arrays back into an S-Expression.
Instance Method Details
#convertLiterals(data) ⇒ Object
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/schaefer/parser.rb', line 103 def convertLiterals(data) return recursiveMap(data) do |x| case x when nil then [] when true then :"#t" when false then :"#f" else x end end end |
#convertTokens(tokens) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/schaefer/parser.rb', line 64 def convertTokens(tokens) convertedTokens = [] tokens.each do |token| convertedTokens << "(" and next if token == "(" convertedTokens << ")" and next if token == ")" convertedTokens << token.to_i and next if isInteger?(token) convertedTokens << token.to_sym and next if isSymbol?(token) convertedTokens << eval(token) and next if isString?(token) convertedTokens << token and next if isComma?(token) raise Exception, "Unrecognized token: #{token}" end return convertedTokens end |
#formStructure(tokens, offset = 0) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/schaefer/parser.rb', line 78 def formStructure(tokens, offset = 0) structure = [] while offset < tokens.length do if tokens[offset] == "(" offset, tempArray = formStructure(tokens, offset + 1) structure << tempArray elsif tokens[offset] == ")" break else structure << tokens[offset] end offset += 1 end return [offset, structure] end |
#isComma?(string) ⇒ Boolean
60 61 62 |
# File 'lib/schaefer/parser.rb', line 60 def isComma?(string) return isMatch?(string, /.*,.*/) end |
#isInteger?(string) ⇒ Boolean
return true if string is made of any number of numerals optionally preceded by a + or -
52 53 54 |
# File 'lib/schaefer/parser.rb', line 52 def isInteger?(string) #return true if string is made of any number of numerals optionally preceded by a + or - return isMatch?(string, /[\-\+]?[0-9]+/) end |
#isMatch?(string, pattern) ⇒ Boolean
check if type is a match, returns false if no, true if yes
42 43 44 45 46 |
# File 'lib/schaefer/parser.rb', line 42 def isMatch?(string, pattern) #check if type is a match, returns false if no, true if yes match = string.match(pattern) return false unless match match[0].length == string.length end |
#isString?(string) ⇒ Boolean
return true if string is text surrounded by quotes
56 57 58 |
# File 'lib/schaefer/parser.rb', line 56 def isString?(string) #return true if string is text surrounded by quotes return isMatch?(string, /"([^"\\]|\\.)*"/) end |
#isSymbol?(string) ⇒ Boolean
return true if string is anything other than parenthasees, quotes, or commas
48 49 50 |
# File 'lib/schaefer/parser.rb', line 48 def isSymbol?(string) #return true if string is anything other than parenthasees, quotes, or commas return isMatch?(string, /[^\"\'\,\(\)]+/) end |
#parse(string) ⇒ Object
94 95 96 97 98 99 100 101 |
# File 'lib/schaefer/parser.rb', line 94 def parse(string) string, literals = pullSLiterals(string) tokens = tokenize(string) tokens = replaceSLiterals(tokens, literals) tokens = convertTokens(tokens) structure = formStructure(tokens)[1] return structure end |
#pullSLiterals(string) ⇒ Object
method used to remove all string literals, save them in an array, and replace them with a set string that will not interfere with parsing
3 4 5 6 7 8 9 10 11 12 |
# File 'lib/schaefer/parser.rb', line 3 def pullSLiterals(string) #method used to remove all string literals, save them in an array, and replace them with a set string that will not interfere with parsing pattern = /"([^"\\]|\\.)*"/ replace = "***STRING-LITERAL***" literals = [] string.gsub(pattern) do |occurence| literals << occurence end string = string.gsub(pattern, replace) return [string, literals] end |
#replaceSLiterals(tokens, literals) ⇒ Object
method used to restore string literals in our tokens array now that we dont have to worry about special cases
32 33 34 35 36 37 38 39 40 |
# File 'lib/schaefer/parser.rb', line 32 def replaceSLiterals(tokens, literals) #method used to restore string literals in our tokens array now that we dont have to worry about special cases return tokens.map do |token| if token == "***STRING-LITERAL***" literals.shift else token end end end |
#tokenize(string) ⇒ Object
method used split program into tokens by adding spaces arround ‘(’s and calling string.split(‘ ’)
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/schaefer/parser.rb', line 14 def tokenize(string) #method used split program into tokens by adding spaces arround '('s and calling string.split(' ') numOpen = string.count("(") numClose = string.count(")") numMissing = 0 if numOpen > numClose numMissing = numOpen - numClose raise RuntimeError, "#{numMissing} missing close parenthasees" elsif numClose > numOpen numMissing = numClose - numOpen raise RuntimeError, "#{numMissing} extra close parenthasees" elsif numClose == numOpen string = string.gsub("(", " ( ") string = string.gsub(")", " ) ") tokens = string.split(" ") return tokens end end |
#toToken(data) ⇒ Object
Convert a set of nested arrays back into an S-Expression
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/schaefer/parser.rb', line 115 def toToken(data) data = convertLiterals(data) if(data.is_a?(Array)) mapped = data.map do |item| if(item.is_a?(Array)) toToken(item) else item.to_s end end "(" + mapped.join(" ") + ")" elsif (data.is_a?(Hash)) mapped = data.map do |key, value| key = toToken(key) value = toToken(value) key + "=>" + value end "(" + mapped.join(" ") + ")" else data.to_s end end |