Initial Revision
[ohcount] / ext / ohcount_native / glots / polyglot.rb
1 require 'monoglot'
2
3 module Ohcount
4         # A Polyglot is a compile-time code generator.
5         # It generates C code which defines the states and transitions
6         # required for a complex parser which can span multiple languages.
7         #
8         # For instance, an HTML parser might understand Javascript, CSS, and
9         # basic HTML. All of these languages would be defined in Monoglots,
10         # then the overall HTML parser would be defined as a Polyglot
11         # spanning several Monoglots.
12         class Polyglot < Monoglot
13                 # Transitions above and beyond those defined in the child Monoglots.
14                 # These are transitions which move us from a state in one Monoglot to
15                 # a state in another Monoglot.
16                 attr_reader :extra_transitions
17
18                 # The Polyglot may require additional states beyond those defined in the
19                 # child Monoglots. Those extra states are defined here.
20                 attr_reader :extra_states
21
22                 def print_states(io)
23                         #define each
24                         io.puts "/* States */"
25                         @extra_states.each do |s|
26                                 s.print(io)
27                         end
28
29                         # now define the collection
30                         io.write "State *#{ name.upcase }_STATES[] = { "
31                         all_states.each do |s|
32                                 io.write "&#{ s.definition }, "
33                         end
34                         io.write "NULL };\n"
35                 end
36
37                 def all_states
38                         @extra_states + @states
39                 end
40
41                 def all_transitions
42                         @extra_transitions + @transitions
43                 end
44
45                 def print_transitions(io)
46                         io.puts "/* Transitions */"
47                         # print each transition
48                         @extra_transitions.each do |t|
49                                 t.print(io)
50                         end
51
52                         #aggregate the transitions
53                         io.write  "Transition *#{ name.upcase }_TRANSITIONS[] = {"
54                         all_transitions.each do |t|
55                                 io.write " &#{ t.definition },"
56                         end
57                         io.write " NULL};\n"
58                 end
59         end
60 end