rltk 2.2.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +12 -12
- data/README.md +458 -285
- data/Rakefile +99 -92
- data/lib/rltk/ast.rb +221 -126
- data/lib/rltk/cfg.rb +218 -239
- data/lib/rltk/cg/basic_block.rb +1 -1
- data/lib/rltk/cg/bindings.rb +9 -26
- data/lib/rltk/cg/builder.rb +40 -8
- data/lib/rltk/cg/context.rb +1 -1
- data/lib/rltk/cg/contractor.rb +51 -0
- data/lib/rltk/cg/execution_engine.rb +45 -8
- data/lib/rltk/cg/function.rb +12 -2
- data/lib/rltk/cg/generated_bindings.rb +2541 -575
- data/lib/rltk/cg/generic_value.rb +2 -2
- data/lib/rltk/cg/instruction.rb +104 -83
- data/lib/rltk/cg/llvm.rb +44 -3
- data/lib/rltk/cg/memory_buffer.rb +22 -5
- data/lib/rltk/cg/module.rb +85 -36
- data/lib/rltk/cg/old_generated_bindings.rb +6152 -0
- data/lib/rltk/cg/pass_manager.rb +87 -43
- data/lib/rltk/cg/support.rb +2 -4
- data/lib/rltk/cg/target.rb +158 -28
- data/lib/rltk/cg/triple.rb +8 -8
- data/lib/rltk/cg/type.rb +69 -25
- data/lib/rltk/cg/value.rb +107 -66
- data/lib/rltk/cg.rb +16 -17
- data/lib/rltk/lexer.rb +21 -11
- data/lib/rltk/lexers/calculator.rb +1 -1
- data/lib/rltk/lexers/ebnf.rb +8 -7
- data/lib/rltk/parser.rb +300 -247
- data/lib/rltk/parsers/infix_calc.rb +1 -1
- data/lib/rltk/parsers/postfix_calc.rb +2 -2
- data/lib/rltk/parsers/prefix_calc.rb +2 -2
- data/lib/rltk/token.rb +1 -2
- data/lib/rltk/version.rb +3 -3
- data/lib/rltk.rb +6 -6
- data/test/cg/tc_basic_block.rb +83 -0
- data/test/cg/tc_control_flow.rb +191 -0
- data/test/cg/tc_function.rb +54 -0
- data/test/cg/tc_generic_value.rb +33 -0
- data/test/cg/tc_instruction.rb +256 -0
- data/test/cg/tc_llvm.rb +25 -0
- data/test/cg/tc_math.rb +88 -0
- data/test/cg/tc_module.rb +89 -0
- data/test/cg/tc_transforms.rb +68 -0
- data/test/cg/tc_type.rb +69 -0
- data/test/cg/tc_value.rb +151 -0
- data/test/cg/ts_cg.rb +23 -0
- data/test/tc_ast.rb +105 -8
- data/test/tc_cfg.rb +63 -48
- data/test/tc_lexer.rb +84 -96
- data/test/tc_parser.rb +224 -52
- data/test/tc_token.rb +6 -6
- data/test/ts_rltk.rb +12 -15
- metadata +149 -75
- data/lib/rltk/cg/generated_extended_bindings.rb +0 -287
- data/lib/rltk/util/abstract_class.rb +0 -25
- data/lib/rltk/util/monkeys.rb +0 -129
data/lib/rltk/cg/value.rb
CHANGED
@@ -7,8 +7,10 @@
|
|
7
7
|
# Requires #
|
8
8
|
############
|
9
9
|
|
10
|
+
# Gems
|
11
|
+
require 'filigree/abstract_class'
|
12
|
+
|
10
13
|
# Ruby Language Toolkit
|
11
|
-
require 'rltk/util/abstract_class'
|
12
14
|
require 'rltk/cg/bindings'
|
13
15
|
require 'rltk/cg/type'
|
14
16
|
|
@@ -16,7 +18,7 @@ require 'rltk/cg/type'
|
|
16
18
|
# Classes and Modules #
|
17
19
|
#######################
|
18
20
|
|
19
|
-
module RLTK::CG
|
21
|
+
module RLTK::CG
|
20
22
|
|
21
23
|
# This class represents LLVM IR "data", including integer and float
|
22
24
|
# literals, functions, and constant arrays, structs, and vectors.
|
@@ -50,9 +52,9 @@ module RLTK::CG # :nodoc:
|
|
50
52
|
#
|
51
53
|
# @param [Type] type Type to cast to.
|
52
54
|
#
|
53
|
-
# @return [
|
55
|
+
# @return [ConstantExpr]
|
54
56
|
def bitcast(type)
|
55
|
-
|
57
|
+
ConstantExpr.new(Bindings.const_bit_cast(@ptr, check_cg_type(type)))
|
56
58
|
end
|
57
59
|
|
58
60
|
# @return [Boolean] If this value is a constant.
|
@@ -87,7 +89,7 @@ module RLTK::CG # :nodoc:
|
|
87
89
|
#
|
88
90
|
# @return [String] *str*
|
89
91
|
def name=(str)
|
90
|
-
|
92
|
+
str.tap { Bindings.set_value_name(@ptr, check_type(str, String)) }
|
91
93
|
end
|
92
94
|
|
93
95
|
# @return [Boolean] If the value is null or not.
|
@@ -95,42 +97,27 @@ module RLTK::CG # :nodoc:
|
|
95
97
|
Bindings.is_null(@ptr).to_bool
|
96
98
|
end
|
97
99
|
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
#
|
102
|
-
# @LLVMECB
|
103
|
-
#
|
104
|
-
# @param [String, #fileno] io File name or object with a file descriptor to print to.
|
105
|
-
#
|
106
|
-
# @return [void]
|
107
|
-
def print(io = $stdout)
|
108
|
-
case io
|
109
|
-
when String
|
110
|
-
File.open(io, 'w') do |f|
|
111
|
-
Bindings.print_value(@ptr, f.fileno)
|
112
|
-
end
|
113
|
-
else
|
114
|
-
Bindings.print_value(@ptr, io.fileno)
|
115
|
-
end
|
100
|
+
# @return [String] LLVM IR representation of this value
|
101
|
+
def print
|
102
|
+
Bindings.print_value_to_string(@ptr)
|
116
103
|
end
|
117
104
|
|
118
105
|
# Truncate a value to a given type.
|
119
106
|
#
|
120
107
|
# @param [Type] type Type to truncate to.
|
121
108
|
#
|
122
|
-
# @return [
|
109
|
+
# @return [ConstantExpr]
|
123
110
|
def trunc(type)
|
124
|
-
|
111
|
+
ConstantExpr.new(Bindings.const_trunc(check_cg_type(type)))
|
125
112
|
end
|
126
113
|
|
127
114
|
# Truncate or bitcast a value to the given type as is appropriate.
|
128
115
|
#
|
129
116
|
# @param [Type] type Type to cast or truncate to.
|
130
117
|
#
|
131
|
-
# @return [
|
118
|
+
# @return [ConstantExpr]
|
132
119
|
def trunc_or_bitcast(type)
|
133
|
-
|
120
|
+
ConstantExpr.new(Bindings.const_trunc_or_bit_cast(check_cg_type(type)))
|
134
121
|
end
|
135
122
|
|
136
123
|
# @return [Type] Type of this value.
|
@@ -147,18 +134,18 @@ module RLTK::CG # :nodoc:
|
|
147
134
|
#
|
148
135
|
# @param [Type] type Type to extend the value to.
|
149
136
|
#
|
150
|
-
# @return [
|
137
|
+
# @return [ConstantExpr]
|
151
138
|
def zextend(type)
|
152
|
-
|
139
|
+
ConstantExpr.new(Bindings.const_z_ext(check_cg_type(type)))
|
153
140
|
end
|
154
141
|
|
155
142
|
# Zero extend or bitcast the value to the given type as is appropriate.
|
156
143
|
#
|
157
144
|
# @param [Type] type Type to cast or extend to.
|
158
145
|
#
|
159
|
-
# @return [
|
146
|
+
# @return [ConstantExpr]
|
160
147
|
def zextend_or_bitcast(type)
|
161
|
-
|
148
|
+
ConstantExpr.new(Bindings.const_z_ext_or_bit_cast(check_cg_type(type)))
|
162
149
|
end
|
163
150
|
|
164
151
|
# This class is used to access a {Value Value's} attributes.
|
@@ -227,7 +214,7 @@ module RLTK::CG # :nodoc:
|
|
227
214
|
#
|
228
215
|
# @abstract
|
229
216
|
class User < Value
|
230
|
-
include AbstractClass
|
217
|
+
include Filigree::AbstractClass
|
231
218
|
|
232
219
|
# @return [OperandCollection] Proxy object for accessing a value's operands.
|
233
220
|
def operands
|
@@ -286,7 +273,7 @@ module RLTK::CG # :nodoc:
|
|
286
273
|
#
|
287
274
|
# @abstract
|
288
275
|
class Constant < User
|
289
|
-
include AbstractClass
|
276
|
+
include Filigree::AbstractClass
|
290
277
|
|
291
278
|
# Create a new constant from a pointer or a type. As a library user
|
292
279
|
# you should never pass a pointer in here as that is only used
|
@@ -306,11 +293,20 @@ module RLTK::CG # :nodoc:
|
|
306
293
|
end
|
307
294
|
end
|
308
295
|
|
296
|
+
# Cast a constant to a given address space
|
297
|
+
#
|
298
|
+
# @param [Type] type Type to cast to
|
299
|
+
#
|
300
|
+
# @return [ConstantExpr]
|
301
|
+
def addr_space_cast(type)
|
302
|
+
ConstantExpr.new(Bindings.const_addr_space_cast(@ptr, check_cg_type(type)))
|
303
|
+
end
|
304
|
+
|
309
305
|
# Bitcast a constant to a given type.
|
310
306
|
#
|
311
|
-
# @param [Type]
|
307
|
+
# @param [Type] type Type to cast to
|
312
308
|
#
|
313
|
-
# @return [
|
309
|
+
# @return [ConstantExpr]
|
314
310
|
def bitcast_to(type)
|
315
311
|
ConstantExpr.new(Bindings.const_bit_cast(@ptr, check_cg_type(type)))
|
316
312
|
end
|
@@ -351,7 +347,7 @@ module RLTK::CG # :nodoc:
|
|
351
347
|
#
|
352
348
|
# @param [FFI::Pointer] ptr
|
353
349
|
def initialize(ptr)
|
354
|
-
@ptr =
|
350
|
+
@ptr = check_type(ptr, FFI::Pointer, 'ptr')
|
355
351
|
end
|
356
352
|
end
|
357
353
|
|
@@ -374,7 +370,7 @@ module RLTK::CG # :nodoc:
|
|
374
370
|
#
|
375
371
|
# @abstract
|
376
372
|
class ConstantAggregate < Constant
|
377
|
-
include AbstractClass
|
373
|
+
include Filigree::AbstractClass
|
378
374
|
|
379
375
|
# Extract values from a constant aggregate value.
|
380
376
|
#
|
@@ -414,14 +410,19 @@ module RLTK::CG # :nodoc:
|
|
414
410
|
#
|
415
411
|
# @yieldparam index [Integer] Index of the value in the array.
|
416
412
|
#
|
417
|
-
# @param [Type]
|
418
|
-
# @param [Array<Value>, Integer]
|
419
|
-
# @param [Proc]
|
413
|
+
# @param [Type] element_type Type of values in this aggregate.
|
414
|
+
# @param [Array<Value>, Integer] size_or_values Number of values or array of values.
|
415
|
+
# @param [Proc] block Block evaluated if size is specified.
|
420
416
|
def initialize(element_type, size_or_values, &block)
|
421
|
-
vals_ptr
|
422
|
-
|
423
|
-
@ptr
|
417
|
+
vals_ptr = make_ptr_to_elements(size_or_values, &block)
|
418
|
+
element_type = check_cg_type(element_type, Type, 'element_type')
|
419
|
+
@ptr = Bindings.const_array(element_type, vals_ptr, vals_ptr.size / vals_ptr.type_size)
|
424
420
|
end
|
421
|
+
|
422
|
+
def size
|
423
|
+
self.type.size
|
424
|
+
end
|
425
|
+
alias :length :size
|
425
426
|
end
|
426
427
|
|
427
428
|
# A sub-class of {ConstantArray} specifically for holding strings.
|
@@ -464,7 +465,8 @@ module RLTK::CG # :nodoc:
|
|
464
465
|
|
465
466
|
@ptr =
|
466
467
|
if context
|
467
|
-
Bindings.const_struct_in_context(check_type(context, Context, 'context'),
|
468
|
+
Bindings.const_struct_in_context(check_type(context, Context, 'context'),
|
469
|
+
vals_ptr, vals_ptr.size / vals_ptr.type_size, packed.to_i)
|
468
470
|
else
|
469
471
|
Bindings.const_struct(vals_ptr, vals_ptr.size / vals_ptr.type_size, packed.to_i)
|
470
472
|
end
|
@@ -498,17 +500,17 @@ module RLTK::CG # :nodoc:
|
|
498
500
|
|
499
501
|
# @param [Integer] index Index of desired element.
|
500
502
|
#
|
501
|
-
# @return [
|
503
|
+
# @return [ConstantExpr] Extracted element.
|
502
504
|
def extract_element(index)
|
503
|
-
|
505
|
+
ConstantExpr.new(Bindings.const_extract_element(@ptr, index))
|
504
506
|
end
|
505
507
|
|
506
508
|
# @param [Value] element Value to insert into the vector.
|
507
509
|
# @param [Integer] index Index to insert the value at.
|
508
510
|
#
|
509
|
-
# @return [
|
511
|
+
# @return [ConstantExpr] New vector representation with inserted value.
|
510
512
|
def insert_element(element, index)
|
511
|
-
|
513
|
+
ConstantExpr.new(Bindings.const_insert_element(@ptr, element, index))
|
512
514
|
end
|
513
515
|
|
514
516
|
# @param [ConstantVector] other Other vector to shuffle with this one.
|
@@ -518,13 +520,18 @@ module RLTK::CG # :nodoc:
|
|
518
520
|
def shuffle(other, mask)
|
519
521
|
ConstantVector.new(Bindings.const_shuffle_vector(@ptr, other, mask))
|
520
522
|
end
|
523
|
+
|
524
|
+
def size
|
525
|
+
self.type.size
|
526
|
+
end
|
527
|
+
alias :length :size
|
521
528
|
end
|
522
529
|
|
523
530
|
# All number constants inherit from this class.
|
524
531
|
#
|
525
532
|
# @abstract
|
526
533
|
class ConstantNumber < Constant
|
527
|
-
include AbstractClass
|
534
|
+
include Filigree::AbstractClass
|
528
535
|
|
529
536
|
# @return [Type] The corresponding Type sub-class that is used to represent the type of this value.
|
530
537
|
def self.type
|
@@ -541,7 +548,7 @@ module RLTK::CG # :nodoc:
|
|
541
548
|
#
|
542
549
|
# @abstract
|
543
550
|
class ConstantInteger < ConstantNumber
|
544
|
-
include AbstractClass
|
551
|
+
include Filigree::AbstractClass
|
545
552
|
|
546
553
|
# @return [Boolean] If the integer is signed or not.
|
547
554
|
attr_reader :signed
|
@@ -560,9 +567,10 @@ module RLTK::CG # :nodoc:
|
|
560
567
|
# @example Constant integer of all 1s:
|
561
568
|
# Int32.new
|
562
569
|
#
|
563
|
-
# @param [FFI::Pointer, Integer, String, nil]
|
564
|
-
# @param [Boolean, Integer]
|
565
|
-
#
|
570
|
+
# @param [FFI::Pointer, Integer, String, nil] overloaded0 Pointer to a ConstantInteger, value, or string representing value.
|
571
|
+
# @param [Boolean, Integer] overloaded1 Signed or unsigned (when overloaded0 is Integer) or base used to
|
572
|
+
# decode string value.
|
573
|
+
# @param [Integer] size Optional length of string to use.
|
566
574
|
def initialize(overloaded0 = nil, overloaded1 = nil, size = nil)
|
567
575
|
@ptr =
|
568
576
|
case overloaded0
|
@@ -925,7 +933,7 @@ module RLTK::CG # :nodoc:
|
|
925
933
|
#
|
926
934
|
# @abstract
|
927
935
|
class ConstantReal < ConstantNumber
|
928
|
-
include AbstractClass
|
936
|
+
include Filigree::AbstractClass
|
929
937
|
|
930
938
|
# Create a constant real number using a Ruby value or a string.
|
931
939
|
#
|
@@ -1046,16 +1054,18 @@ module RLTK::CG # :nodoc:
|
|
1046
1054
|
end
|
1047
1055
|
end
|
1048
1056
|
|
1057
|
+
# A 16-bit floating point number value.
|
1058
|
+
class Half < ConstantReal; end
|
1049
1059
|
# A double precision floating point number value.
|
1050
|
-
class Double
|
1051
|
-
# A single precision floating point number
|
1052
|
-
class Float
|
1053
|
-
# A 128 bit (16 byte) floating point number
|
1054
|
-
class FP128
|
1055
|
-
# A 128 bit (16 byte) floating point number
|
1056
|
-
class PPCFP128
|
1057
|
-
# A 80 bit (10 byte) floating point number
|
1058
|
-
class X86FP80
|
1060
|
+
class Double < ConstantReal; end
|
1061
|
+
# A single precision floating point number value.
|
1062
|
+
class Float < ConstantReal; end
|
1063
|
+
# A 128 bit (16 byte) floating point number value.
|
1064
|
+
class FP128 < ConstantReal; end
|
1065
|
+
# A 128 bit (16 byte) floating point number value for the PPC architecture.
|
1066
|
+
class PPCFP128 < ConstantReal; end
|
1067
|
+
# A 80 bit (10 byte) floating point number value for the x86 architecture.
|
1068
|
+
class X86FP80 < ConstantReal; end
|
1059
1069
|
|
1060
1070
|
# This class represents global constants, variables, and functions.
|
1061
1071
|
class GlobalValue < Constant
|
@@ -1090,6 +1100,22 @@ module RLTK::CG # :nodoc:
|
|
1090
1100
|
Bindings.is_declaration(@ptr).to_bool
|
1091
1101
|
end
|
1092
1102
|
|
1103
|
+
# Sets the externally initialized property of a global value.
|
1104
|
+
#
|
1105
|
+
# @param [Boolean] bool If the value is externally initialized
|
1106
|
+
#
|
1107
|
+
# @return [void]
|
1108
|
+
def externally_initialized=(bool)
|
1109
|
+
Bindings.set_externally_initialized(@ptr, bool.to_i)
|
1110
|
+
end
|
1111
|
+
|
1112
|
+
# Check if this global is initialized externally.
|
1113
|
+
#
|
1114
|
+
# @return [Boolean]
|
1115
|
+
def externally_initialized?
|
1116
|
+
Bindings.externally_initialized(@ptr).to_bool
|
1117
|
+
end
|
1118
|
+
|
1093
1119
|
# Check if this value is a global constant.
|
1094
1120
|
#
|
1095
1121
|
# @return [Boolean]
|
@@ -1158,6 +1184,23 @@ module RLTK::CG # :nodoc:
|
|
1158
1184
|
Bindings.set_section(@ptr, section)
|
1159
1185
|
end
|
1160
1186
|
|
1187
|
+
# Returns the thread local model used by a global value.
|
1188
|
+
#
|
1189
|
+
# @return [Symbol from _enum_thread_local_mode_]
|
1190
|
+
def thread_local_mode
|
1191
|
+
Bindings.get_thread_local_mode(@ptr)
|
1192
|
+
end
|
1193
|
+
|
1194
|
+
|
1195
|
+
# Set the global value's thread local mode.
|
1196
|
+
#
|
1197
|
+
# @param [Symbol from _enum_thread_local_mode_] mode
|
1198
|
+
#
|
1199
|
+
# @return [void]
|
1200
|
+
def thread_local_mode=(mode)
|
1201
|
+
Bindings.set_thread_local_mode(@ptr, mode)
|
1202
|
+
end
|
1203
|
+
|
1161
1204
|
# Get this value's visibility.
|
1162
1205
|
#
|
1163
1206
|
# @see Bindings._enum_visibility_
|
@@ -1225,7 +1268,5 @@ def make_ptr_to_elements(size_or_values, &block)
|
|
1225
1268
|
size_or_values
|
1226
1269
|
end
|
1227
1270
|
|
1228
|
-
|
1229
|
-
ptr.write_array_of_pointer(values)
|
1230
|
-
end
|
1271
|
+
FFI::MemoryPointer.new(:pointer, values.size).write_array_of_pointer(values)
|
1231
1272
|
end
|
data/lib/rltk/cg.rb
CHANGED
@@ -8,26 +8,25 @@
|
|
8
8
|
# Classes and Modules #
|
9
9
|
#######################
|
10
10
|
|
11
|
-
module RLTK
|
12
|
-
|
11
|
+
module RLTK
|
13
12
|
# This module contains classes and methods for code generation. Code
|
14
13
|
# generation functionality is provided by bindings to
|
15
14
|
# [LLVM](http://llvm.org).
|
16
15
|
module CG
|
17
|
-
autoload :BasicBlock,
|
18
|
-
autoload :Bindings,
|
19
|
-
autoload :Builder,
|
20
|
-
autoload :Context,
|
21
|
-
autoload :ExecutionEngine,
|
22
|
-
autoload :Function,
|
23
|
-
autoload :GenericValue,
|
24
|
-
autoload :Instruction,
|
25
|
-
autoload :LLVM,
|
26
|
-
autoload :MemoryBuffer,
|
27
|
-
autoload :Module,
|
28
|
-
autoload :PassManager,
|
29
|
-
autoload :Support,
|
30
|
-
autoload :Type,
|
31
|
-
autoload :Value,
|
16
|
+
autoload :BasicBlock, 'rltk/cg/basic_block'
|
17
|
+
autoload :Bindings, 'rltk/cg/bindings'
|
18
|
+
autoload :Builder, 'rltk/cg/builder'
|
19
|
+
autoload :Context, 'rltk/cg/context'
|
20
|
+
autoload :ExecutionEngine, 'rltk/cg/execution_engine'
|
21
|
+
autoload :Function, 'rltk/cg/function'
|
22
|
+
autoload :GenericValue, 'rltk/cg/generic_value'
|
23
|
+
autoload :Instruction, 'rltk/cg/instruction'
|
24
|
+
autoload :LLVM, 'rltk/cg/llvm'
|
25
|
+
autoload :MemoryBuffer, 'rltk/cg/memory_buffer'
|
26
|
+
autoload :Module, 'rltk/cg/module'
|
27
|
+
autoload :PassManager, 'rltk/cg/pass_manager'
|
28
|
+
autoload :Support, 'rltk/cg/support'
|
29
|
+
autoload :Type, 'rltk/cg/type'
|
30
|
+
autoload :Value, 'rltk/cg/value'
|
32
31
|
end
|
33
32
|
end
|
data/lib/rltk/lexer.rb
CHANGED
@@ -17,11 +17,21 @@ require 'rltk/token'
|
|
17
17
|
# Classes and Modules #
|
18
18
|
#######################
|
19
19
|
|
20
|
-
module RLTK
|
21
|
-
|
20
|
+
module RLTK
|
22
21
|
# A LexingError exception is raised when an input stream contains a
|
23
22
|
# substring that isn't matched by any of a lexer's rules.
|
24
23
|
class LexingError < StandardError
|
24
|
+
# @return [Integer]
|
25
|
+
attr_reader :stream_offset
|
26
|
+
|
27
|
+
# @return [Integer]
|
28
|
+
attr_reader :line_number
|
29
|
+
|
30
|
+
# @return [Integer]
|
31
|
+
attr_reader :line_offset
|
32
|
+
|
33
|
+
# @return [String]
|
34
|
+
attr_reader :remainder
|
25
35
|
|
26
36
|
# @param [Integer] stream_offset Offset from begnning of string.
|
27
37
|
# @param [Integer] line_number Number of newlines encountered so far.
|
@@ -55,6 +65,14 @@ module RLTK # :nodoc:
|
|
55
65
|
# @return [Symbol] State in which the lexer starts.
|
56
66
|
attr_reader :start_state
|
57
67
|
|
68
|
+
# Called when the Lexer class is sub-classed, it installes
|
69
|
+
# necessary instance class variables.
|
70
|
+
#
|
71
|
+
# @return [void]
|
72
|
+
def inherited(klass)
|
73
|
+
klass.install_icvars
|
74
|
+
end
|
75
|
+
|
58
76
|
# Installs instance class varialbes into a class.
|
59
77
|
#
|
60
78
|
# @return [void]
|
@@ -63,14 +81,6 @@ module RLTK # :nodoc:
|
|
63
81
|
@rules = Hash.new {|h,k| h[k] = Array.new}
|
64
82
|
@start_state = :default
|
65
83
|
end
|
66
|
-
|
67
|
-
# Called when the Lexer class is sub-classed, it installes
|
68
|
-
# necessary instance class variables.
|
69
|
-
#
|
70
|
-
# @return [void]
|
71
|
-
def inherited(klass)
|
72
|
-
klass.install_icvars
|
73
|
-
end
|
74
84
|
|
75
85
|
# Lex *string*, using *env* as the environment. This method will
|
76
86
|
# return the array of tokens generated by the lexer with a token
|
@@ -137,7 +147,7 @@ module RLTK # :nodoc:
|
|
137
147
|
line_offset += txt.length()
|
138
148
|
end
|
139
149
|
else
|
140
|
-
error = LexingError.new(stream_offset, line_number, line_offset, scanner.
|
150
|
+
error = LexingError.new(stream_offset, line_number, line_offset, scanner.rest)
|
141
151
|
raise(error, 'Unable to match string with any of the given rules')
|
142
152
|
end
|
143
153
|
end
|
data/lib/rltk/lexers/ebnf.rb
CHANGED
@@ -14,8 +14,8 @@ require 'rltk/lexer'
|
|
14
14
|
# Classes and Modules #
|
15
15
|
#######################
|
16
16
|
|
17
|
-
module RLTK
|
18
|
-
module Lexers
|
17
|
+
module RLTK
|
18
|
+
module Lexers
|
19
19
|
|
20
20
|
# The EBNF lexer is used by the RLTK::CFG class.
|
21
21
|
class EBNF < Lexer
|
@@ -24,12 +24,13 @@ module RLTK # :nodoc:
|
|
24
24
|
# Default State #
|
25
25
|
#################
|
26
26
|
|
27
|
-
rule(/\*/)
|
28
|
-
rule(/\+/)
|
29
|
-
rule(/\?/)
|
27
|
+
rule(/\*/) { :STAR }
|
28
|
+
rule(/\+/) { :PLUS }
|
29
|
+
rule(/\?/) { :QUESTION }
|
30
|
+
rule(/\./) { :DOT }
|
30
31
|
|
31
|
-
rule(/[a-z0-9_]+/)
|
32
|
-
rule(/[A-Z0-9_]+/)
|
32
|
+
rule(/[a-z0-9_']+/) { |t| [:NONTERM, t.to_sym] }
|
33
|
+
rule(/[A-Z0-9_']+/) { |t| [:TERM, t.to_sym] }
|
33
34
|
|
34
35
|
rule(/\s/)
|
35
36
|
end
|