Class: Antelope::Ace::Scanner

Inherits:
Object
  • Object
show all
Includes:
First, Second, Third
Defined in:
lib/antelope/ace/scanner.rb,
lib/antelope/ace/scanner/first.rb,
lib/antelope/ace/scanner/third.rb,
lib/antelope/ace/scanner/second.rb,
lib/antelope/ace/scanner/argument.rb

Overview

Scans a given input. The input should be a properly formatted ACE file; see the Ace module for more information. This scanner uses the StringScanner class internally; see the ruby documentation for more on that. This scanner seperates scanning into three seperate stages: First, Second, and Third, for each section of the file, respectively.

Defined Under Namespace

Modules: First, Second, Third Classes: Argument

Constant Summary collapse

IDENTIFIER =
"[a-zA-Z_.][a-zA-Z0-9_.-]*"
CONTENT_BOUNDRY =

The boundry between each section. Placed here to be easily. modifiable. MUST be a regular expression.

Returns:

  • (RegExp)
/%%/
VALUE =

The value regular expression. It should match values; for example, things quoted in strings or word letters without quotes. Must respond to #to_s, since it is embedded within other regular expressions. The regular expression should place the contents of the value in the groups 2 or 3.

Returns:

  • (#to_s)
%q{(?:
    (?:("|')((?:\\\\|\\"|\\'|.)+?)\\1)
  | ([A-Za-z0-9_.<>*-]+)
)}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Third

#scan_third_part

Methods included from Second

#_scan_block, #scan_second_part, #scan_second_rule, #scan_second_rule_block, #scan_second_rule_body, #scan_second_rule_label, #scan_second_rule_or, #scan_second_rule_part, #scan_second_rule_prec

Methods included from First

#scan_first_copy, #scan_first_directive, #scan_first_directive_arguments, #scan_first_part

Constructor Details

#initialize(input, source = "(ace file)") ⇒ Scanner

Initialize the scanner with the input.

Parameters:

  • input (String)

    The source to scan.

  • source (String) (defaults to: "(ace file)")

    the source file. This is primarily used in backtrace information.



74
75
76
77
78
# File 'lib/antelope/ace/scanner.rb', line 74

def initialize(input, source = "(ace file)")
  @source  = source
  @scanner = StringScanner.new(input)
  @tokens  = []
end

Instance Attribute Details

#scannerStringScanner (readonly)

The string scanner that we're using to scan the string with.

Returns:

  • (StringScanner)


32
33
34
# File 'lib/antelope/ace/scanner.rb', line 32

def scanner
  @scanner
end

#tokensArray<Array<(Symbol, Object, ...)>> (readonly)

An array of the tokens that the scanner scanned.

Returns:

  • (Array<Array<(Symbol, Object, ...)>>)


37
38
39
# File 'lib/antelope/ace/scanner.rb', line 37

def tokens
  @tokens
end

Class Method Details

.scan(source, name = "(ace file)") ⇒ Array<Array<(Symbol, Object, ...)>>

Scans a file. It returns the tokens resulting from scanning.

Parameters:

  • source (String)

    the source to scan. This should be compatible with StringScanner.

  • name (String) (defaults to: "(ace file)")

    the name of the source file. This is primarilyused in backtrace information.

Returns:

  • (Array<Array<(Symbol, Object, ...)>>)

See Also:



65
66
67
# File 'lib/antelope/ace/scanner.rb', line 65

def self.scan(source, name = "(ace file)")
  new(source, name).scan_file
end

Instance Method Details

#error!void (private)

This method returns an undefined value.

Raises an error.

Raises:



139
140
141
# File 'lib/antelope/ace/scanner.rb', line 139

def error!
  raise SyntaxError, "invalid syntax"
end

#scan_commentBoolean

Scans for a comment. If the next token is a number sign (#), it will consume all characters until the next newline.

Returns:

  • (Boolean)

    if a comment was matched.



127
128
129
130
131
# File 'lib/antelope/ace/scanner.rb', line 127

def scan_comment
  if @scanner.scan(/\#(.*)\n/)
    @line += 1
  end
end

#scan_fileArray<Array<(Symbol, Object, ...)>>

Scans the file in parts.

Returns:

  • (Array<Array<(Symbol, Object, ...)>>)

    the tokens that were scanned in this file.

Raises:

  • (SyntaxError)

    if the source is malformed in some way.

See Also:



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/antelope/ace/scanner.rb', line 89

def scan_file
  @line = 1
  scan_first_part
  scan_second_part
  scan_third_part
  tokens
rescue SyntaxError => e
  start = [@scanner.pos - 8, 0].max
  stop  = [@scanner.pos + 8, @scanner.string.length].min
  snip  = @scanner.string[start..stop].strip.inspect
  char  = @scanner.string[@scanner.pos]
  char = if char
    char.inspect
  else
    "EOF"
  end

  new_line = "#{@source}:#{@line}: unexpected #{char} " \
    "(near #{snip})"

  raise e, e.message, [new_line, *e.backtrace]
end

#scan_whitespaceBoolean

Scans for whitespace. If the next character is whitespace, it will consume all whitespace until the next non-whitespace character.

Returns:

  • (Boolean)

    if any whitespace was matched.



117
118
119
120
121
# File 'lib/antelope/ace/scanner.rb', line 117

def scan_whitespace
  if @scanner.scan(/(\s+)/)
    @line += @scanner[1].count("\n")
  end
end