The parser for SassScript. It parses a string of code into a tree of {Script::Node}s.
It would be possible to have unified assert and try methods, but detecting the method/token difference turns out to be quite expensive.
Returns whether or not the given operation is associative.
@private
# File lib/sass/script/parser.rb, line 195 def associative?(op) ASSOCIATIVE.include?(op) end
@param str [String, StringScanner] The source text to parse @param line [Fixnum] The line on which the SassScript appears.
Used for error reporting
@param offset [Fixnum] The number of characters in on which the SassScript appears.
Used for error reporting
@param options [{Symbol => Object}] An options hash;
see {file:SASS_REFERENCE.md#sass_options the Sass options documentation}
# File lib/sass/script/parser.rb, line 22 def initialize(str, line, offset, options = {}) @options = options @lexer = lexer_class.new(str, line, offset, options) end
Parses a SassScript expression.
@overload parse(str, line, offset, filename = nil) @return [Script::Node] The root node of the parse tree @see Parser#initialize @see #parse
# File lib/sass/script/parser.rb, line 165 def self.parse(*args) new(*args).parse end
Returns an integer representing the precedence of the given operator. A lower integer indicates a looser binding.
@private
# File lib/sass/script/parser.rb, line 185 def precedence_of(op) PRECEDENCE.each_with_index do |e, i| return i if Array(e).include?(op) end raise "[BUG] Unknown operator #{op}" end
The line number of the parser’s current position.
@return [Fixnum]
# File lib/sass/script/parser.rb, line 11 def line @lexer.line end
Parses a SassScript expression.
@return [Script::Node] The root node of the parse tree @raise [Sass::SyntaxError] if the expression isn’t valid SassScript
# File lib/sass/script/parser.rb, line 48 def parse expr = assert_expr :expr assert_done expr.options = @options expr rescue Sass::SyntaxError => e e.modify_backtrace :line => @lexer.line, :filename => @options[:filename] raise e end
Parses the argument list for a function definition.
@return [(Array<Script::Node>, Script::Node)]
The root nodes of the arguments, and the splat argument.
@raise [Sass::SyntaxError] if the argument list isn’t valid SassScript
# File lib/sass/script/parser.rb, line 123 def parse_function_definition_arglist args, splat = defn_arglist!(true) assert_done args.each do |k, v| k.options = @options v.options = @options if v end splat.options = @options if splat return args, splat rescue Sass::SyntaxError => e e.modify_backtrace :line => @lexer.line, :filename => @options[:filename] raise e end
Parses a SassScript expression within an interpolated segment (`#{}`). This means that it stops when it comes across an unmatched `}`, which signals the end of an interpolated segment, it returns rather than throwing an error.
@return [Script::Node] The root node of the parse tree @raise [Sass::SyntaxError] if the expression isn’t valid SassScript
# File lib/sass/script/parser.rb, line 34 def parse_interpolated expr = assert_expr :expr assert_tok :end_interpolation expr.options = @options expr rescue Sass::SyntaxError => e e.modify_backtrace :line => @lexer.line, :filename => @options[:filename] raise e end
Parses the argument list for a mixin definition.
@return [(Array<Script::Node>, Script::Node)]
The root nodes of the arguments, and the splat argument.
@raise [Sass::SyntaxError] if the argument list isn’t valid SassScript
# File lib/sass/script/parser.rb, line 103 def parse_mixin_definition_arglist args, splat = defn_arglist!(false) assert_done args.each do |k, v| k.options = @options v.options = @options if v end splat.options = @options if splat return args, splat rescue Sass::SyntaxError => e e.modify_backtrace :line => @lexer.line, :filename => @options[:filename] raise e end
Parses the argument list for a mixin include.
@return [(Array<Script::Node>, {String => Script::Node}, Script::Node)]
The root nodes of the positional arguments, keyword arguments, and splat argument. Keyword arguments are in a hash from names to values.
@raise [Sass::SyntaxError] if the argument list isn’t valid SassScript
# File lib/sass/script/parser.rb, line 81 def parse_mixin_include_arglist args, keywords = [], {} if try_tok(:lparen) args, keywords, splat = mixin_arglist || [[], {}] assert_tok(:rparen) end assert_done args.each {|a| a.options = @options} keywords.each {|k, v| v.options = @options} splat.options = @options if splat return args, keywords, splat rescue Sass::SyntaxError => e e.modify_backtrace :line => @lexer.line, :filename => @options[:filename] raise e end
Parse a single string value, possibly containing interpolation. Doesn’t assert that the scanner is finished after parsing.
@return [Script::Node] The root node of the parse tree. @raise [Sass::SyntaxError] if the string isn’t valid SassScript
# File lib/sass/script/parser.rb, line 143 def parse_string unless (peek = @lexer.peek) && (peek.type == :string || (peek.type == :funcall && peek.value.downcase == 'url')) lexer.expected!("string") end expr = assert_expr :funcall expr.options = @options @lexer.unpeek! expr rescue Sass::SyntaxError => e e.modify_backtrace :line => @lexer.line, :filename => @options[:filename] raise e end
Parses a SassScript expression, ending it when it encounters one of the given identifier tokens.
@param [include?(String)] A set of strings that delimit the expression. @return [Script::Node] The root node of the parse tree @raise [Sass::SyntaxError] if the expression isn’t valid SassScript
# File lib/sass/script/parser.rb, line 64 def parse_until(tokens) @stop_at = tokens expr = assert_expr :expr assert_done expr.options = @options expr rescue Sass::SyntaxError => e e.modify_backtrace :line => @lexer.line, :filename => @options[:filename] raise e end