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.



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

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

Instance Attribute Details

#allow_includeObject

a subset of restricted mode which allows include files



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

def allow_include
  @allow_include
end

#allow_restrictedObject

like installing new files from within files



21
22
23
# File 'lib/yay/parser.rb', line 21

def allow_restricted
  @allow_restricted
end

#shutdownObject (readonly)

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



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

def shutdown
  @shutdown
end

Instance Method Details

#autoformat(strings) ⇒ Object

takes strings without colours and automatically assigns one to each



47
48
49
50
# File 'lib/yay/parser.rb', line 47

def autoformat strings
  autoformatter = Yay::Autoformatter.new
  @ruleset.merge autoformatter.get_rules strings
end

#current_positionObject

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



187
188
189
# File 'lib/yay/parser.rb', line 187

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)


108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/yay/parser.rb', line 108

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



161
162
163
# File 'lib/yay/parser.rb', line 161

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



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/yay/parser.rb', line 138

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



102
103
104
# File 'lib/yay/parser.rb', line 102

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



96
97
98
99
# File 'lib/yay/parser.rb', line 96

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



53
54
55
56
57
58
# File 'lib/yay/parser.rb', line 53

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

#include_or_autoformat(strings) ⇒ Object

tries to include a file if it exists; otherwise autoformats



36
37
38
39
40
41
42
43
44
# File 'lib/yay/parser.rb', line 36

def include_or_autoformat strings
  begin
    include_file strings[0].source
  rescue Yay::CouldntFindFileError
    # autoformat if we're on the commandline otherwise this doesn't make
    # sense
    autoformat strings if @allow_restricted
  end
end

#install_file(file_name, url) ⇒ Object

install a file from a url



61
62
63
64
65
66
# File 'lib/yay/parser.rb', line 61

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

#list_installedObject

print the full list of yay files



69
70
71
72
73
74
# File 'lib/yay/parser.rb', line 69

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

#next_tokenObject

get the next token



181
182
183
# File 'lib/yay/parser.rb', line 181

def next_token
	@lexer.next_token
end

#on_error(error_token_id, error_value, cant_touch_this) ⇒ Object

the racc on_error function



192
193
194
195
# File 'lib/yay/parser.rb', line 192

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



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

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)


166
167
168
169
# File 'lib/yay/parser.rb', line 166

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



125
126
127
128
129
130
131
132
133
134
# File 'lib/yay/parser.rb', line 125

def string_to_regex string, escape=true
    # extract the constituent part of the regexp. in ruby 1.8 we can't just
    # create a regex from a perl-style regex literal like /abc/i
	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



87
88
89
90
91
92
93
# File 'lib/yay/parser.rb', line 87

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