Class: Yay::Parser

Inherits:
ParserGen show all
Defined in:
lib/yay/parser.rb

Overview

extends the parser that was automatically generated by racc and adds the behaviour necessary. this separation is done only because it’s difficult to use .y files for anything other than grammar rules, even if they do allow ruby code

Constant Summary

Constants inherited from ParserGen

Yay::ParserGen::Racc_arg, Yay::ParserGen::Racc_debug_parser, Yay::ParserGen::Racc_token_to_s_table

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from ParserGen

#_reduce_none

Constructor Details

#initialize(context_name = nil) ⇒ Parser

Returns a new instance of Parser.



37
38
39
40
# File 'lib/yay/parser.rb', line 37

def initialize context_name=nil
	@lexer = Yay::Lexer.new
	@lexer.context_name = context_name
end

Instance Attribute Details

#allow_defaultObject

allow this parser to load the default rule file if the rule body is empty



19
20
21
# File 'lib/yay/parser.rb', line 19

def allow_default
  @allow_default
end

#allow_includeObject

allow this parser to include rule files that are installed. including ones in the gem folders, globally and locally



27
28
29
# File 'lib/yay/parser.rb', line 27

def allow_include
  @allow_include
end

#allow_installObject

allow this parser to install new rule files from remote sources. beware the consequences. this should be allowed from the command line only!



23
24
25
# File 'lib/yay/parser.rb', line 23

def allow_install
  @allow_install
end

#allow_listObject

allow this parser to search for and print out all the rules that are installed



31
32
33
# File 'lib/yay/parser.rb', line 31

def allow_list
  @allow_list
end

#shutdownObject (readonly)

set to true to signal to the application or parent parser that it’s time to shut down



35
36
37
# File 'lib/yay/parser.rb', line 35

def shutdown
  @shutdown
end

Instance Method Details

#allow_all=(value) ⇒ Object

allow all parser actions



67
68
69
# File 'lib/yay/parser.rb', line 67

def allow_all= value
	@allow_default = @allow_install = @allow_include = @allow_list = value
end

#current_positionObject

get location information from the lexer in a nice little array we can pass to an exception constructor



170
171
172
# File 'lib/yay/parser.rb', line 170

def current_position
	return [@lexer.position, @lexer.line, @lexer.context_name]
end

#extract_regexp_options(args) ⇒ Object

for lack of a better function, this will take the ending sequence from a regular expression and convert it in to a bytewise options variable

Raises:

  • (ArgumentError)


93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/yay/parser.rb', line 93

def extract_regexp_options args
	return 0 if args.nil?
	raise ArgumentError unless args.kind_of? String
	options_map = {
		'i' => Regexp::IGNORECASE,
		'm' => Regexp::MULTILINE,
		'x' => Regexp::EXTENDED,
	}
	options = 0
	args.each { |char|
		options |= options_map[char] || 0
	}
	return options
end

#get_rulesObject

get the end result of the parse



144
145
146
# File 'lib/yay/parser.rb', line 144

def get_rules
	@ruleset.get_rules
end

#handle_colours(colours) ⇒ Object

given an array of colour strings, create an array with the VT100 colour sequences inside



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/yay/parser.rb', line 121

def handle_colours colours
	fg = bg = nil
	result = []
	# iterate the colour list and try to find up to two colours (foreground,
	# background) and unlimited miscellaneous colours (reset, invert, etc)
	colours.each { |colour| 
		misc_val = ColourWheel::MISC[colour]
		if !misc_val.nil?
			result.push misc_val
		elsif !fg
			fg = ColourWheel::FG[colour]
			result.push fg
		elsif !bg
			bg = ColourWheel::BG[colour]
			result.push bg
		else
			raise Yay::TooManyColoursError.new fg, bg, colour, current_position
		end
	}
	result
end

#handle_regex(string) ⇒ Object

process a regex token in to something we can use



87
88
89
# File 'lib/yay/parser.rb', line 87

def handle_regex string
	return string_to_regex string, false
end

#handle_string(string) ⇒ Object

process a string token in to something we can use



81
82
83
84
# File 'lib/yay/parser.rb', line 81

def handle_string string
	string = Regexp::escape(string)
	return Regexp.new(string, Regexp::IGNORECASE)
end

#include_file(filename) ⇒ Object

load a file from a url



43
44
45
46
47
48
# File 'lib/yay/parser.rb', line 43

def include_file filename
	raise NotAllowedError.new "include #{filename}", current_position unless @allow_include
	loader = Yay::Loader.new filename
	loader.load
	@ruleset.merge loader.get_rules
end

#install_file(file_name, url) ⇒ Object

install a file from a url



51
52
53
54
55
56
# File 'lib/yay/parser.rb', line 51

def install_file file_name, url
	raise NotAllowedError.new "install #{url}", current_position unless @allow_install
	installer = Yay::Installer.new file_name, url
	installer.install
	@shutdown = true
end

#list_installedObject

print the full list of yay files



59
60
61
62
63
64
# File 'lib/yay/parser.rb', line 59

def list_installed
	raise NotAllowedError.new "list installed yay files", current_position unless @allow_list
	lister = Yay::Lister.new 
    lister.print
    @shutdown = true
end

#next_tokenObject

get the next token



164
165
166
# File 'lib/yay/parser.rb', line 164

def next_token
	@lexer.next_token
end

#on_error(error_token_id, error_value, cant_touch_this) ⇒ Object

the racc on_error function



175
176
177
178
# File 'lib/yay/parser.rb', line 175

def on_error error_token_id, error_value, cant_touch_this
	type = token_to_str error_token_id
	raise Yay::UnexpectedTokenError.new type, error_value, current_position
end

#parse(str) ⇒ Object

parse a string. returns the results



155
156
157
158
159
160
161
# File 'lib/yay/parser.rb', line 155

def parse(str)
	@lexer.use_string(str)
	@ruleset = Yay::RuleSet.new

	do_parse
	return get_rules
end

#parse_array(args) ⇒ Object

process commandline arguments as if they were from a yay file

Raises:

  • (ArgumentError)


149
150
151
152
# File 'lib/yay/parser.rb', line 149

def parse_array args
	raise ArgumentError, "args" unless args.kind_of? Array
	parse args.join(' ')
end

#string_to_regex(string, escape = true) ⇒ Object

for lack of a better function, this will take a string like “/abc/” and transform it in to a regex object



110
111
112
113
114
115
116
117
# File 'lib/yay/parser.rb', line 110

def string_to_regex string, escape=true
	matches = /\/([^\/\\\r\n]*(?:\\.[^\/\\\r\n]*)*)\/([a-z]\b)*/.match string
	return nil if matches[1].nil?
	content = matches[1]
	content = Regexp::escape(content) if escape
	options = extract_regexp_options matches[2]
	return Regexp.new(content, options)
end

#use_default_fileObject

load the default file. used when the commandline is empty



72
73
74
75
76
77
78
# File 'lib/yay/parser.rb', line 72

def use_default_file
	# don't throw an error in this case. it's legitimate for a file to be empty
	return unless @allow_default
	loader = Yay::Loader.default_file_loader
	loader.load
	@ruleset.merge loader.get_rules
end