aurum 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/Rakefile +29 -0
  2. data/examples/dangling_else/grammar.rb +23 -0
  3. data/examples/expression/grammar.rb +28 -0
  4. data/examples/smalltalk/grammar.rb +151 -0
  5. data/examples/smalltalk/interpreter.rb +70 -0
  6. data/examples/yacc/grammar.rb +72 -0
  7. data/lib/aurum.rb +1 -9
  8. data/lib/aurum/engine.rb +39 -175
  9. data/lib/aurum/engine/parsing_facility.rb +107 -0
  10. data/lib/aurum/engine/tokenization_facility.rb +86 -0
  11. data/lib/aurum/grammar.rb +52 -219
  12. data/lib/aurum/grammar/automata.rb +194 -0
  13. data/lib/aurum/grammar/builder/augmented_grammar.rb +83 -0
  14. data/lib/aurum/grammar/builder/dot_logger.rb +66 -0
  15. data/lib/aurum/grammar/builder/lexical_table_builder.rb +55 -0
  16. data/lib/aurum/grammar/builder/parsing_table_builder.rb +238 -0
  17. data/lib/aurum/grammar/builder/set_of_items.rb +190 -0
  18. data/lib/aurum/grammar/compiled_tables.rb +20 -0
  19. data/lib/aurum/grammar/dsl/lexical_definition.rb +94 -0
  20. data/lib/aurum/grammar/dsl/syntax_definition.rb +79 -0
  21. data/lib/aurum/grammar/lexical_rules.rb +224 -0
  22. data/lib/aurum/grammar/metalang/grammar.rb +47 -0
  23. data/lib/aurum/grammar/syntax_rules.rb +95 -0
  24. data/spec/builder/dsl_definition/aurum_grammar_spec.rb +33 -0
  25. data/spec/engine/lexer_spec.rb +59 -0
  26. data/spec/engine/parser_spec.rb +90 -0
  27. data/spec/examples/dangling_else_example.rb +30 -0
  28. data/spec/examples/expression_example.rb +48 -0
  29. data/spec/examples/smalltalk_example.rb +50 -0
  30. data/spec/examples/yacc_spec.rb +30 -0
  31. data/spec/grammar/builder/lexical_table/automata_spec.rb +55 -0
  32. data/spec/grammar/builder/lexical_table/builder_spec.rb +78 -0
  33. data/spec/grammar/builder/lexical_table/character_set_spec.rb +100 -0
  34. data/spec/grammar/builder/lexical_table/pattern_spec.rb +11 -0
  35. data/spec/grammar/builder/lexical_table/regular_expression.rb +40 -0
  36. data/spec/grammar/builder/parsing_table/augmented_grammar_spec.rb +36 -0
  37. data/spec/grammar/builder/parsing_table/builder_spec.rb +152 -0
  38. data/spec/grammar/builder/parsing_table/digraph_traverser_spec.rb +42 -0
  39. data/spec/grammar/builder/parsing_table/item_spec.rb +51 -0
  40. data/spec/grammar/builder/parsing_table/sources_spec.rb +66 -0
  41. data/spec/grammar/builder/parsing_table/state_spec.rb +82 -0
  42. data/spec/grammar/dsl/character_classes_builder_spec.rb +50 -0
  43. data/spec/grammar/dsl/lexical_rules_builder_spec.rb +181 -0
  44. data/spec/grammar/dsl/precedence_builder_spec.rb +64 -0
  45. data/spec/grammar/dsl/productions_builder_spec.rb +78 -0
  46. data/spec/grammar/metalang/metalang_spec.rb +0 -0
  47. data/spec/grammar/precedence_spec.rb +42 -0
  48. data/spec/grammar/syntax_rules_spec.rb +31 -0
  49. data/spec/parser_matcher.rb +69 -0
  50. data/spec/pattern_matcher.rb +123 -0
  51. data/spec/spec_helper.rb +133 -0
  52. metadata +70 -36
  53. data/example/expression/expression.rb +0 -35
  54. data/example/expression/lisp.rb +0 -26
  55. data/lib/aurum/lexical_table_generator.rb +0 -429
  56. data/lib/aurum/parsing_table_generator.rb +0 -464
  57. data/test/engine/lexer_test.rb +0 -59
  58. data/test/engine/semantic_attributes_test.rb +0 -15
  59. data/test/grammar_definition/character_class_definition_test.rb +0 -28
  60. data/test/grammar_definition/grammar_definition_test.rb +0 -55
  61. data/test/grammar_definition/lexical_definition_test.rb +0 -56
  62. data/test/grammar_definition/operator_precedence_definition_test.rb +0 -35
  63. data/test/grammar_definition/production_definition_test.rb +0 -60
  64. data/test/lexical_table_generator/automata_test.rb +0 -74
  65. data/test/lexical_table_generator/character_set_test.rb +0 -73
  66. data/test/lexical_table_generator/interval_test.rb +0 -36
  67. data/test/lexical_table_generator/pattern_test.rb +0 -115
  68. data/test/lexical_table_generator/subset_determinizer_test.rb +0 -19
  69. data/test/lexical_table_generator/table_generator_test.rb +0 -126
  70. data/test/parsing_table_generator/augmented_grammar_test.rb +0 -45
  71. data/test/parsing_table_generator/lalr_n_computation_test.rb +0 -92
  72. data/test/parsing_table_generator/lr_0_automata_test.rb +0 -94
  73. data/test/parsing_table_generator/lr_item_test.rb +0 -27
  74. data/test/parsing_table_generator/parsing_table_state_test.rb +0 -39
  75. data/test/parsing_table_generator/precedence_table_test.rb +0 -28
  76. data/test/parsing_table_generator/production_test.rb +0 -9
  77. data/test/test_helper.rb +0 -103
@@ -0,0 +1,29 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/gempackagetask'
4
+ require 'spec/rake/spectask'
5
+
6
+ spec = Gem::Specification.new do |s|
7
+ s.name = 'aurum'
8
+ s.version = '0.2.0'
9
+ s.author = 'Vincent Xu'
10
+ s.email = 'x at bjug dot org'
11
+ s.homepage = 'http://rubyforge.org/projects/aurum'
12
+ s.platform = Gem::Platform::RUBY
13
+ s.summary = 'Aurum is a LALR(n) parser generator written in Ruby.'
14
+ s.files = FileList['{examples,lib,spec}/**/*', 'Rakefile'].to_a
15
+ s.require_path = 'lib'
16
+ s.autorequire = 'aurum'
17
+ s.has_rdoc = false
18
+ end
19
+
20
+ Rake::GemPackageTask.new(spec) do |pkg|
21
+ pkg.need_tar = true
22
+ end
23
+
24
+ Spec::Rake::SpecTask.new('spec') do |t|
25
+ t.spec_files = FileList['spec/**/*_spec.rb', 'spec/**/*_example.rb']
26
+ t.spec_opts = ['--format', 'html:result.html', '--format', 'specdoc']
27
+ end
28
+
29
+ task :default => [:spec]
@@ -0,0 +1,23 @@
1
+ require 'aurum'
2
+ module Aurum
3
+ module Examples
4
+ class DanglingElse < Aurum::Grammar
5
+ tokens do
6
+ ignore enum(" \r\n").one_or_more
7
+ end
8
+
9
+ productions do
10
+ statement 'if', '(', expression, ')', restricted_statement,
11
+ 'else', statement {statement.s_exp = [:if, expression.s_exp, restricted_statement.s_exp, statement1.s_exp]}
12
+ statement 'if', '(', expression, ')',
13
+ statement {statement.s_exp = [:if, expression.s_exp, statement1.s_exp, nil]}
14
+ statement simple_statement
15
+ restricted_statement 'if', '(', expression, ')', restricted_statement,
16
+ 'else', restricted_statement {statement.s_exp = [:if, expression.s_exp, restricted_statement1.s_exp, restricted_statement2.s_exp]}
17
+ restricted_statement simple_statement
18
+ simple_statement 'other' do simple_statement.s_exp = [:other] end
19
+ expression 'expr' do expression.s_exp = [:expr] end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ require 'aurum'
2
+ module Aurum
3
+ module Examples
4
+ class ExpressionGrammar < Aurum::Grammar
5
+ tokens do
6
+ ignore string(' ').one_or_more
7
+ _number range(?0, ?9).one_or_more
8
+ end
9
+
10
+ precedences do
11
+ left '*', '/'
12
+ left '+', '-'
13
+ end
14
+
15
+ productions do
16
+ expression expression, '+', expression {expression.value = expression1.value + expression2.value}
17
+ expression expression, '-', expression {expression.value = expression1.value - expression2.value}
18
+ expression expression, '*', expression {expression.value = expression1.value * expression2.value}
19
+ expression expression, '/', expression {expression.value = expression1.value / expression2.value}
20
+ expression '(', expression, ')' do expression.value = expression1.value end
21
+ expression _number {expression.value = _number.value.to_i}
22
+ expression '+', _number {expression.value = _number.value.to_i}
23
+ expression '-', _number {expression.value = -_number.value.to_i}
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,151 @@
1
+ require 'aurum'
2
+ =begin
3
+ module Smalltalk
4
+ class UnaryMessageSending < Aurum::Grammar
5
+ productions do
6
+ unary_expression higher_precedence, unary_messages do
7
+ unary_expression.s_exp = [:unary, higher_precedence.s_exp, unary_messages.s_exp]
8
+ end
9
+ unary_messages unary_messages, _message do
10
+ unary_messages.s_exp = unary_messages1.s_exp + [_message.value]
11
+ end
12
+ unary_messages _message do
13
+ unary_messages.s_exp = [_message.value]
14
+ end
15
+ end
16
+ end
17
+
18
+ class BinaryMessageSending < Aurum::Grammar
19
+ productions do
20
+ binary_expression higher_precedence, binary_messages do
21
+ binary_expression.s_exp = [:binary, higher_precedence.s_exp, binary_messages.s_exp]
22
+ end
23
+ binary_messages binary_messages, binary_message do
24
+ binary_messages.s_exp << binary_message.s_exp
25
+ end
26
+ binary_messages binary_message
27
+ binary_message _binary_message, higher_precedence do
28
+ binary_message.s_exp = [[_binary_message.value, higher_precedence.s_exp]]
29
+ end
30
+ end
31
+ end
32
+
33
+ class KeywordMessageSending < Aurum::Grammar
34
+ productions do
35
+ keyword_expression higher_precedence, keyword_messages do
36
+ keyword_expression.s_exp = [:keyword, higher_precedence.s_exp, keyword_messages.s_exp]
37
+ end
38
+ keyword_messages keyword_messages, keyword_message do
39
+ keyword_messages.s_exp = keyword_messages1.s_exp + keyword_message.s_exp
40
+ end
41
+ keyword_messages keyword_message
42
+ keyword_message _keyword, higher_precedence do
43
+ keyword_message.s_exp = [[_keyword.value, higher_precedence.s_exp]]
44
+ end
45
+ end
46
+ end
47
+
48
+ class Block < Aurum::Grammar
49
+ productions do
50
+ block '[', block_parameters, '|', sentences, ']' do
51
+ block.s_exp = [:block, block_parameters.s_exp, sentences.s_exp]
52
+ end
53
+ block '[', sentences, ']' do
54
+ block.s_exp = [:block, [:params], sentences.s_exp]
55
+ end
56
+ block_parameters block_parameters, ':', _identifier do
57
+ block_parameters.s_exp = block_parameters1.s_exp + _identifier.value
58
+ end
59
+ block_parameters ':', _identifier do
60
+ block_parameters.s_exp = [:params, _identifier.value]
61
+ end
62
+ end
63
+ end
64
+
65
+ class Grammar < Aurum::Grammar
66
+ character_classes do
67
+ letter range(?a, ?z) + range(?A, ?Z)
68
+ identifier_tail letter + range(?0, ?9) + enum('_')
69
+ end
70
+
71
+ tokens do
72
+ comment double_quote, ~double_quote
73
+ whitespaces enum(" \r\n").one_or_more
74
+
75
+ identifier letter, identifier_tail.zero_or_more
76
+
77
+ _identifier identifier
78
+ _binary_selector enum('!%&*+/<=>?@~,\\').one_or_more
79
+ _keyword identifier, ':'
80
+ ignore comment
81
+ ignore whitespaces
82
+ end
83
+
84
+ include_grammar UnaryMessageSending, :syntax => {:higher_precedence => :primary, :_message => :_identifier}
85
+ include_grammar BinaryMessageSending, :syntax => {:higher_precedence => :higher_precedence_binary, :_binary_message => :_binary_selector}
86
+ include_grammar KeywordMessageSending,:syntax => {:higher_precedence => :higher_precedence_keyword}
87
+ include_grammar Block
88
+
89
+ productions do
90
+ program variables, sentences do
91
+ program.s_exp = [:program, variables.s_exp, sentences.s_exp]
92
+ end
93
+
94
+ variables '|', identifiers, '|' do
95
+ variables.s_exp = [] + identifiers.s_exp
96
+ end
97
+ variables _ do
98
+ variables.s_exp = []
99
+ end
100
+
101
+ identifiers identifiers, _identifier do
102
+ identifiers.s_exp = identifiers.s_exp + _identifier.value
103
+ end
104
+ identifiers _ do
105
+ identifiers.s_exp = []
106
+ end
107
+
108
+ sentences sentences, expression, '.' do
109
+ sentences.s_exp = sentences1.s_exp + [expression.s_exp]
110
+ end
111
+ sentences _ do
112
+ sentences.s_exp = []
113
+ end
114
+ sentence expression, '.' do
115
+ sentence.s_exp = expression.s_exp
116
+ end
117
+
118
+ expression _identifier, ':=', message_expression do
119
+ expression.s_exp = [:assign, _identifier.value, message_expression.s_exp]
120
+ end
121
+ expression _identifier, ':=', primary do
122
+ expression.s_exp = [:assign, _identifier.value, primary.s_exp]
123
+ end
124
+ expression message_expression
125
+ expression primary
126
+
127
+ primary _identifier do
128
+ primary.s_exp = [:var, _identifier.value]
129
+ end
130
+ primary block
131
+ primary '(', message_expression, ')' do
132
+ primary.s_exp = message_expression.s_exp
133
+ end
134
+ primary '(', primary, ')' do
135
+ primary.s_exp = primary1.s_exp
136
+ end
137
+
138
+ message_expression unary_expression
139
+ message_expression binary_expression
140
+ message_expression keyword_expression
141
+
142
+ higher_precedence_binary primary
143
+ higher_precedence_binary unary_expression
144
+
145
+ higher_precedence_keyword primary
146
+ higher_precedence_keyword unary_expression
147
+ higher_precedence_keyword binary_expression
148
+ end
149
+ end
150
+ end
151
+ =end
@@ -0,0 +1,70 @@
1
+ require File.join(File.dirname(__FILE__), 'grammar')
2
+ require 'stringio'
3
+ =begin
4
+ class Smalltalk::Interpreter
5
+ @@parsing_table = Smalltalk::Grammar.parsing_table :program
6
+ @@lexical_table = Smalltalk::Grammar.lexical_table
7
+
8
+ def initialize context = {}
9
+ @parser = Aurum::Engine::Parser.new(@@parsing_table)
10
+ @context = context
11
+ end
12
+
13
+ def run source
14
+ @lexer = Aurum::Engine::Lexer.new(@@lexical_table, source)
15
+ eval_s_exp(@parser.parse(@lexer).s_exp)
16
+ end
17
+
18
+ private
19
+ def program variables, sentences
20
+ variables.each {|variable| @context[variable] = nil}
21
+ sentences.each {|sentence| eval_s_exp(sentence)}
22
+ end
23
+
24
+ def var name
25
+ @context[name]
26
+ end
27
+
28
+ def unary object_s_exp, unary_messages
29
+ unary_messages.inject((eval_s_exp(object_s_exp))) {|obj, message| obj = obj.send(message)}
30
+ end
31
+
32
+ def binary object_s_exp, binary_messages
33
+ binary_messages.inject((eval_s_exp(object_s_exp))) {|obj, message| obj = obj.send(message.first, eval_s_exp(message.last))}
34
+ end
35
+
36
+ def keyword object_s_exp, keyword_messages
37
+ obj = eval_s_exp(object_s_exp)
38
+ messages, values = '', []
39
+ for keyword_message in keyword_messages
40
+ messages << keyword_message.first
41
+ values << eval_s_exp(keyword_message.last)
42
+ end
43
+ obj.send(messages.gsub(':', '_'), values)
44
+ end
45
+
46
+ def eval_s_exp s_exp
47
+ self.send(s_exp.first, *s_exp[1..-1])
48
+ end
49
+ end
50
+
51
+ class Transcript
52
+ def self.show_ message
53
+ puts message
54
+ end
55
+
56
+ def self.hello
57
+ show_ 'Hello'
58
+ end
59
+ end
60
+
61
+ interpreter = Smalltalk::Interpreter.new 'Transcript' => Transcript,
62
+ 'helloMessage' => 'Hello World'
63
+
64
+ interpreter.run(<<-EOF)
65
+ "keyword message sending"
66
+ Transcript show: helloMessage.
67
+ "unary message sending"
68
+ Transcript hello.
69
+ EOF
70
+ =end
@@ -0,0 +1,72 @@
1
+ require 'aurum'
2
+ module Aurum
3
+ module Examples
4
+ class YaccGrammar < Aurum::Grammar
5
+ character_classes do
6
+ letter range(?a, ?z) + range(?A, ?Z)
7
+ id_tail range(?a, ?z) + range(?A, ?Z) + range(?0, ?9) + string('_')
8
+ comment_char any - enum('*')
9
+ end
10
+
11
+ tokens do
12
+ multi_lines_comment '/*', ~ string('*/')
13
+ single_line_comment '//', ~ (string("\r") | string("\n"))
14
+
15
+ _identifier letter, id_tail.zero_or_more
16
+ _literal "'", ~ string("'")
17
+ _declaration_code '%{', ~ string('%}')
18
+ _union_name '<', ~ string('>')
19
+ _source_code '{', ~ string('}')
20
+
21
+
22
+ ignore enum(" \r\n\t").one_or_more
23
+ ignore multi_lines_comment
24
+ ignore single_line_comment
25
+ end
26
+
27
+ productions do
28
+ grammar tokens, '%%', rules, end_marker
29
+
30
+ tokens tokens, token
31
+ tokens _
32
+
33
+ token '%start', _identifier
34
+ token '%union', _source_code
35
+ token '%token', union_name, symbols
36
+ token '%left', union_name, symbols
37
+ token '%right', union_name, symbols
38
+ token '%nonassoc', union_name, symbols
39
+ token '%type', union_name, symbols
40
+ token _declaration_code
41
+
42
+ symbols symbols, symbol
43
+ symbols symbol
44
+
45
+ symbol _identifier
46
+ symbol _literal
47
+
48
+ end_marker '%%'
49
+ end_marker _
50
+
51
+ union_name _union_name
52
+ union_name _
53
+
54
+ rules rules, rule
55
+ rules _
56
+
57
+ rule _identifier, ':', rule_body, ';'
58
+ rule_body rule_body, '|', rule_handle
59
+ rule_body rule_handle
60
+
61
+ rule_handle symbols, prec, source_code
62
+ rule_handle source_code
63
+
64
+ prec '%prec', symbol
65
+ prec _
66
+
67
+ source_code _source_code
68
+ source_code _
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,10 +1,2 @@
1
- require 'aurum/lexical_table_generator'
2
- require 'aurum/parsing_table_generator'
3
- require 'aurum/engine'
4
1
  require 'aurum/grammar'
5
-
6
- Enumerable.class_eval do
7
- def grep_each condition
8
- condition.kind_of?(Proc) ? each {|x| yield x if condition.call x} : each {|x| yield x if eval(condition.to_s)}
9
- end
10
- end
2
+ require 'aurum/engine'
@@ -1,175 +1,39 @@
1
- module Aurum
2
- IO.class_eval do
3
- def get_char
4
- char, @pushback_char = @pushback_char ? @pushback_char : self.getc, nil
5
- char > 128 ? char * 128 + self.getc : char
6
- end
7
-
8
- def pushback char
9
- @pushback_char = char
10
- end
11
- end
12
-
13
- String.class_eval do
14
- def get_char
15
- @get_char_index = -1 unless @get_char_index
16
- self[@get_char_index += 1]
17
- end
18
-
19
- def eof?
20
- @get_char_index = -1 unless @get_char_index
21
- @get_char_index >= (self.length - 1)
22
- end
23
-
24
- def pushback char
25
- @get_char_index -= 1
26
- end
27
- end
28
-
29
- Symbol.class_eval {attr_accessor :value}
30
- Unknown = Symbol.new '$unknown', true
31
- class Lexer
32
- def initialize table, accepts, lexical_states, input
33
- @table, @accepts, @lexical_states, @input = table, accepts, lexical_states, input
34
- shift_to :initial
35
- end
36
-
37
- def next_symbol
38
- return Aurum::EOF if @input.eof?
39
- @recognized, lexeme, @pushback_symbol = @pushback_symbol, '', nil
40
- until @recognized
41
- next_state, char = @start_state, nil
42
- while next_state
43
- lexeme << char if char
44
- state, char = next_state, @input.get_char
45
- next_state = goto state, char
46
- end
47
- @input.pushback char
48
- return Unknown unless actions = @accepts[state]
49
- if actions.first == IgnoreAction
50
- lexeme = ''
51
- else
52
- actions.first.execute self, lexeme
53
- end
54
- end
55
- @recognized.value = lexeme unless @recognized.value
56
- @recognized
57
- end
58
-
59
- def pushback symbol
60
- @pushback_symbol = symbol
61
- end
62
-
63
- def goto state, input
64
- return nil unless input
65
- next_state = @table[state].find {|tran| tran.symbols.include?(input)}
66
- next_state ? next_state.destination : nil
67
- end
68
-
69
- def shift_to state
70
- @start_state = goto 0, -@lexical_states.index(state)-1
71
- end
72
-
73
- def recognize token
74
- @recognized = Aurum::Symbol.new token, true
75
- end
76
- end
77
-
78
- RecognizeTokenAction.class_eval do
79
- def execute lexer, lexeme
80
- recognized = lexer.recognize token
81
- action.call recognized, lexeme if action
82
- end
83
- end
84
-
85
- ChangeStateAction.class_eval do
86
- def execute lexer, lexeme
87
- lexer.shift_to state
88
- end
89
- end
90
-
91
- RecognizeTokenAndChangeStateAction.class_eval do
92
- def execute lexer, lexeme
93
- lexer.recognize token
94
- lexer.shift_to state
95
- end
96
- end
97
-
98
- class Parser
99
- def initialize productions, parsing_table
100
- @productions, @parsing_table = productions, parsing_table
101
- end
102
-
103
- def parse lexer
104
- lookahead, state_stack, symbol_stack, value_stack = lexer.next_symbol, [0], [], []
105
- lookahead_shift = 0
106
- while (true)
107
- state = @parsing_table[state_stack.last]
108
- action = state[lookahead]
109
- if action.kind_of? ShiftAction
110
- state_stack.push action.state
111
- symbol_stack.push lookahead unless action.is_lookahead_shift
112
- action.is_lookahead_shift ? lookahead_shift += 1 : lookahead = lexer.next_symbol
113
- elsif action.kind_of? ReduceAction
114
- handle = @productions[action.handle]
115
- lookahead_shift.times { state_stack.pop }
116
- lookahead_shift = 0
117
- if action.is_read_reduce
118
- state_stack.push state
119
- symbol_stack.push lookahead
120
- lookahead = lexer.next_symbol
121
- end
122
- state_stack.slice! -handle.symbols.length..-1
123
- symbols = symbol_stack.slice! -handle.symbols.length..-1
124
- handle.nonterminal == Aurum::START and return value_stack.pop
125
- if handle.action
126
- context = {handle.nonterminal.name => [SemanticAttributes.new]}
127
- handle.symbols.reverse.each_with_index do |symbol, index|
128
- context[symbol.name] = [] unless context.has_key? symbol.name
129
- context[symbol.name] << (symbol.is_terminal ? symbols[-index-1] : value_stack.pop)
130
- end
131
- SemanticActionContext.new(context).instance_eval &handle.action
132
- value_stack.push context[handle.nonterminal.name][0] if context[handle.nonterminal.name]
133
- end
134
- goto = @parsing_table[state_stack.last][handle.nonterminal]
135
- if goto.kind_of? ShiftAction
136
- state_stack.push goto.state
137
- symbol_stack.push nil
138
- else
139
- lexer.pushback lookahead
140
- lookahead = handle.nonterminal
141
- end
142
- else
143
- error_recover
144
- end
145
- end
146
- end
147
-
148
- class SemanticActionContext
149
- instance_methods.each { |m| undef_method m unless m =~ /^__/ || m == 'new' || m=='instance_eval'}
150
- def initialize hash
151
- @hash = hash
152
- end
153
-
154
- def method_missing name, *args
155
- name_string = name.to_s
156
- index = name_string =~ /\d+/ ? name_string.slice!(/\d+/).to_i : 0
157
- @hash[name_string][-index] and return @hash[name_string][-index]
158
- SemanticAttributes.new
159
- end
160
- end
161
-
162
- class SemanticAttributes
163
- instance_methods.each { |m| undef_method m unless m =~ /^__/ || m == 'new'}
164
- def initialize
165
- @hash = {}
166
- end
167
-
168
- def method_missing name, *args
169
- name_string = name.to_s
170
- return @hash[name_string] unless name_string[-1] == 61
171
- @hash[name_string.slice(0..-2)] = args.first
172
- end
173
- end
174
- end
175
- end
1
+ require File.join(File.dirname(__FILE__), 'engine/parsing_facility')
2
+ require File.join(File.dirname(__FILE__), 'engine/tokenization_facility.rb')
3
+
4
+ module Aurum
5
+ class Parser
6
+ def Parser.new grammar, start_symbol
7
+ Class.new do
8
+ @@parsing_table, @@semantic_actions = grammar.start_from(start_symbol)
9
+ include Aurum::Engine::BasicParsingCapability
10
+ include Aurum::Engine::SemanticActionExecutable
11
+ private
12
+ def parsing_table
13
+ @@parsing_table
14
+ end
15
+ def semantic_actions
16
+ @@semantic_actions
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ class Lexer
23
+ def Lexer.new grammar
24
+ Class.new do
25
+ @@lexical_table = grammar.lexical_table
26
+ include Aurum::Engine::BasicTokenizationCapability
27
+ def initialize input
28
+ @input = Aurum::Engine::PushbackString.new(input)
29
+ @states, @line, @column, @push_back = [], 0, 0, []
30
+ shift_to('initial')
31
+ end
32
+ private
33
+ def lexical_table
34
+ @@lexical_table
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end