rltk 2.2.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|