Guest User

Untitled

a guest
Feb 20th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.16 KB | None | 0 0
  1. require ENV['TM_SUPPORT_PATH'] + "/lib/escape.rb"
  2. class Lexer
  3. Token = Struct.new(:name, :pattern)
  4.  
  5. def initialize
  6. @tokens = Array.new
  7. end
  8.  
  9. def add_token(*args)
  10. @tokens << Token.new(*args)
  11. end
  12.  
  13. def lex(data)
  14. copy, result = data.dup, Array.new
  15. until copy.empty?
  16. @tokens.find { |t|
  17. copy.sub!(t.pattern, "") && (t.name.nil? || result << [t.name, $&])
  18. } || raise(ArgumentError, "Malformed data could not be lexed correctly: #{data.inspect}. Copy is: #{copy.inspect.inspect}. Parsed is: #{result.inspect}")
  19. end
  20. result
  21. end
  22. end
  23. class CommandParser
  24. def self.snippet(str)
  25. self.parse(self.lex(str))
  26. end
  27. def self.lex(str)
  28. lexer = Lexer.new
  29. [ [ :fun_begin, /\A(?:\w|\.)*\(/ ],
  30. [ :assignment, /\A[\w.]+\s*<?=(?!=)\s*/ ],
  31. [ :term, /\A[$\w.]+(?=,|)/ ],
  32. [ :term, /\A\.\.\./ ],
  33. [ :comma, /\A,\s*/ ],
  34. [ :fun_end, /\A\)/ ],
  35. [ :quoted, /\A"(?:\\.|[^\\"]+)*"/ ],
  36. [ :quoted, /\A'(?:\\.|[^\\']+)*'/ ],
  37. [ :operator, /\A\s*([\+\-\*\/^]|&&|\|\||!=?|<=?|>=?|==|~|%|;)\s*/ ],
  38. [ :number, /\A\d+(\.\d+)?/ ],
  39. [ :brace_begin, /\A\{/ ],
  40. [ :brace_end, /\A\}/ ],
  41. [ :bracket_begin, /\A\[/ ],
  42. [ :bracket_end, /\A\]/ ],
  43. [ :list_separator, /\A:/ ],
  44. [ nil, /\A\s+/ ] ].each do |name, regex|
  45. lexer.add_token(name, regex)
  46. end
  47. lexer.lex(str)
  48. end
  49. def self.parse(data)
  50. snippet = ""
  51. snippet_counter = -1
  52. stack = []
  53. until data.empty?
  54. type,match = data.shift
  55. if !stack.empty? && stack.last == :assignment && type.to_s =~ /comma|end$/ then
  56. snippet << "}"
  57. stack.pop
  58. end
  59. case type
  60. when :fun_begin, :brace_begin, :bracket_begin
  61. stack << :group
  62. snippet << "${#{snippet_counter+=1}:#{e_sn match}${#{snippet_counter+=1}:"
  63. when :assignment
  64. stack << :assignment
  65. snippet << "#{e_sn match}${#{snippet_counter+=1}:"
  66. when :comma
  67. snippet << ("}${#{snippet_counter+=1}:" + e_sn(match))
  68. when :brace_end, :bracket_end, :fun_end
  69. snippet << "}#{e_sn match}}"
  70. stack.pop
  71. when :quoted
  72. snippet << "${#{snippet_counter+=1}:#{match[0..0]}${#{snippet_counter+=1}:#{e_sn match[1..-2].gsub("}","\\}")}}#{match[-1..-1]}}"
  73. else
  74. snippet << e_sn(match)
  75. end
  76. end
  77. (pp stack;raise "Too many levels: #{snippet}. ") unless stack.length == 0
  78. snippet[4..-2]
  79. end
  80. end
Add Comment
Please, Sign In to add comment