class Steamd::Parser

Parses steam language files. Give access to the parsed data via classes, imports and enums methods.

@example Parsing a Steam Language file

parser = Parser.new
parser.load! # loads the grammars, sets up the parser
parser.parse(File.open('./message.steamd'))

Constants

Error

The base Parser error

NotLoadedError

Thrown if the the parse method is called before the parser is loaded

ParseError

Thrown if there was any non specific Parse error.

StreamNotParsed

Thrown if the callee tries to access the parsed data before parse is called

Public Instance Methods

classes() click to toggle source

Returns an array of classes parsed from the IO stream. The array contains hashes with class information and variables.

The hash is the hash form of ClassStatement

@example Accessing the classes

parser.classes # => [{ name: 'test', variables: [], ...]

@return [Array<Hash>] an array of hashes representing the class @see ClassStatement

# File lib/steamd/parser.rb, line 90
def classes
  raise StreamNotParsed, 'you must parse first' if @tree.nil?

  classes = statements.select do |node|
    node.is_a?(ClassStatement)
  end

  classes.map(&:to_hash)
end
enums() click to toggle source

Returns an array of eneums parsed from the IO stream. The array contains hashes with enum information and variables.

The hash is the hash form of EnumStatement

@example Accessing the enums

parser.enums # => [{ name: 'test', variables: [], ...]

@return [Array<Hash>] an array of hashes representing the class @see EnumStatement

# File lib/steamd/parser.rb, line 110
def enums
  raise StreamNotParsed, 'you must parse first' if @tree.nil?

  enums = statements.select do |node|
    node.is_a?(EnumStatement)
  end

  enums.map(&:to_hash)
end
error()
Alias for: last_error
imports() click to toggle source

An array of hashes containing the imports found in the parsed Steam Language file.

The hash is the hash version of ImportStatement

@example Accessing imports

parser.imports # => [{filename: 'test'}]

@return [Array<Hash>] an array of hashes representing the imports found @see ImportStatement

# File lib/steamd/parser.rb, line 70
def imports
  raise StreamNotParsed, 'you must parse first' if @tree.nil?

  imports = statements.select do |node|
    node.is_a?(ImportStatement)
  end

  imports.map(&:to_hash)
end
last_error() click to toggle source

Returns a hash representing the reason the parser failed.

@example

parser.last_error # => { reason: "Missing ';'", column: 1, line: 12 }
# File lib/steamd/parser.rb, line 124
def last_error
  {
    reason: @parser.failure_reason,
    column: @parser.failure_column,
    line: @parser.failure_line
  }
end
Also aliased as: error
load!() click to toggle source

Load the grammars

@return [Bool] returns true unless an exception is thrown

# File lib/steamd/parser.rb, line 30
def load!
  return if loaded?

  Treetop.load("#{Steamd.grammar_dir}/shared.treetop")

  Dir.glob("#{Steamd.grammar_dir}/*.treetop") do |file|
    Treetop.load(file)
  end

  @parser = SteamdParser.new
  true
end
parse(io) click to toggle source

Parses an IO stream.

@param io [#read, rewind] An IO stream containing the Steam Language

data.

@return [Bool] returns true unless an error is thrown

# File lib/steamd/parser.rb, line 48
def parse(io)
  io.rewind
  raise NotLoadedError, 'load before parsing (#load!)' if @parser.nil?

  data = strip_comments_and_obsolete_tags!(io)

  @tree = @parser.parse(data)
  raise_parser_error! if @tree.nil?

  true
end

Private Instance Methods

loaded?() click to toggle source

@api private

# File lib/steamd/parser.rb, line 136
def loaded?
  !@parser.nil?
end
raise_parser_error!() click to toggle source

@api private

# File lib/steamd/parser.rb, line 146
def raise_parser_error!
  raise ParseError, "Parsing failed: #{error[:reason]} "\
                          "(col: #{error[:column]}, ln: #{error[:line]}"
end
statements() click to toggle source

@api private

# File lib/steamd/parser.rb, line 141
def statements
  @tree.statements
end
strip_comments_and_obsolete_tags!(io) click to toggle source

Fully reads the IO stream, and removes all comments and obsolete tags

# File lib/steamd/parser.rb, line 153
def strip_comments_and_obsolete_tags!(io)
  io.read.strip.gsub(%r{\/\/.*}, '').gsub(/\;\s?obsolete.*/, ';')
end