Class: Rutile::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/rutile/lexer.rb

Defined Under Namespace

Classes: Token

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fsm, files) ⇒ Parser

Returns a new instance of Parser.



18
19
20
21
22
23
24
# File 'lib/rutile/lexer.rb', line 18

def initialize(fsm, files)
    @fsm  = fsm
    @file_stack = []
    @next_files = files.reverse
    @curr_file = nil
    dec_stack
end

Instance Attribute Details

#file_stackObject

Returns the value of attribute file_stack.



16
17
18
# File 'lib/rutile/lexer.rb', line 16

def file_stack
  @file_stack
end

Instance Method Details

#dec_stackObject

decrease the file stack



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/rutile/lexer.rb', line 79

def dec_stack()
    @curr_file.close if @curr_file
    file = @next_files.pop
    if (file == nil)
       @curr_file = nil
    elsif file.class == String
        @curr_file = open(file)
    else
        @curr_file = file
    end
end

#inc_stack(new_file) ⇒ Object

increase the file stack



92
93
94
95
96
97
98
99
# File 'lib/rutile/lexer.rb', line 92

def inc_stack(new_file)
    @file_stack.append(@curr_file)
    if new_file.class == String
        @curr_file = open(file)
    else
        @curr_file = file
    end
end

#parseObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/rutile/lexer.rb', line 26

def parse()
    @fsm.reset
    Enumerator.new do |out|
        char = nil
        string = ""
        recovery_string = ""
        return_val = @fsm.val
        buffer = []
        while @curr_file
            # reached the end of the file
            if (@curr_file.eof && buffer.empty?)
                dec_stack
                ret = Token.new(return_val, string)
                @fsm.reset
                string = ""
                out << ret
            else
                # advance the scanner
                if buffer.empty?
                    char = @curr_file.readchar
                else
                    char = buffer.pop
                end
                temp_val = @fsm.feed char
                if (temp_val == [] && return_val == [])
                    throw "unexpected char '#{char}' following string '#{string}'"
                end
            end

            # hit a match
            if (temp_val == [] && return_val != [])
                ret = Token.new(return_val, string)
                string = ""
                recovery_string += char
                buffer = recovery_string.chars + buffer                        
                return_val = []
                out << ret
                @fsm.reset
                next
            elsif (temp_val == :transition_state)
                recovery_string += char
            elsif (temp_val != [])
                recovery_string = ""
                return_val = temp_val
            end

            # extend the match string
            string += char
        end
    end
end