-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathparserbase.rb
More file actions
102 lines (83 loc) · 1.99 KB
/
parserbase.rb
File metadata and controls
102 lines (83 loc) · 1.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
require 'compilererror'
require 'scanner'
require 'tokens'
require 'pp'
require 'ast'
# Base-class for all Parsers.
# Defines some common methods for parsing sourcecode.
class ParserBase
include Tokens
include AST
# The constructor takes a Scanner instance as an argument
# to read the source code to parse from.
def initialize(scanner)
@scanner = scanner
end
def kleene
res = E[position]
while e = yield
res << e
end
res
end
def position
@scanner.position
end
def literal(str)
@scanner.expect_str(str)
end
def expect(*args)
args.each do |a|
r = @scanner.expect(a)
return r if r
end
return nil
end
def keyword(arg)
Tokens::Keyword.expect(@scanner,arg)
end
def expected(name)
error("Expected: #{name}")
end
def nolfws
@scanner.nolfws
end
def ws
@scanner.ws
end
# Returns filename from which parser reads code.
def filename
@scanner.filename
end
# Returns true, if the parser gets code from a file.
def from_file?
!@scanner.filename.nil?
end
# Output error message by raising an exception.
# Error message contains filename and linenumber, if reading from a file.
# Otherwise, the message only contains the current linenumber and the error message.
def error(message)
if from_file?
# Location and source context will be added automatically by CompilerError#message
full_message = "Parse error: #{message}"
raise ParseError.new(full_message,
filename,
@scanner.lineno,
@scanner.col)
else
raise ParseError.new("Parse error: #{message}",
nil,
@scanner.lineno)
end
end
# Set the scanner used by the parser for ws/nolfws/position etc.
def scanner=(s)
@scanner = s
end
protected
# Protected accessor method for the scanner object.
# For use in subclasses.
def scanner
@scanner
end
end