lib/activefacts/cql/compiler.rb in activefacts-0.8.16 vs lib/activefacts/cql/compiler.rb in activefacts-0.8.18
- old
+ new
@@ -10,21 +10,28 @@
require 'activefacts/cql/compiler/clause'
require 'activefacts/cql/compiler/fact_type'
require 'activefacts/cql/compiler/expression'
require 'activefacts/cql/compiler/fact'
require 'activefacts/cql/compiler/constraint'
-require 'activefacts/cql/compiler/join'
+require 'activefacts/cql/compiler/query'
module ActiveFacts
module CQL
class Compiler < ActiveFacts::CQL::Parser
+ LANGUAGES = {
+ 'en' => 'English',
+ 'fr' => 'French',
+ 'cn' => 'Mandarin'
+ }
attr_reader :vocabulary
- def initialize(filename = "stdin")
- @filename = filename
+ def initialize *a
+ @filename = a.shift || "stdio"
+ super *a
@constellation = ActiveFacts::API::Constellation.new(ActiveFacts::Metamodel)
- debug :file, "Parsing '#{filename}'"
+ @language = nil
+ debug :file, "Parsing '#{@filename}'"
end
def compile_file filename
old_filename = @filename
@filename = filename
@@ -33,12 +40,29 @@
end
@filename = old_filename
@vocabulary
end
+ # Load the appropriate natural language module
+ def detect_language
+ @filename =~ /.*\.(..)\.cql$/i
+ language_code = $1
+ @language = LANGUAGES[language_code] || 'English'
+ end
+
+ def include_language
+ detect_language unless @langage
+ require 'activefacts/cql/Language/'+@language
+ language_module = ActiveFacts::CQL.const_get(@language)
+ extend language_module
+ end
+
def compile input
+ include_language
+
@string = input
+
# The syntax tree created from each parsed CQL statement gets passed to the block.
# parse_all returns an array of the block's non-nil return values.
ok = parse_all(@string, :definition) do |node|
debug :parse, "Parsed '#{node.text_value.gsub(/\s+/,' ').strip}'" do
begin
@@ -67,13 +91,16 @@
end
def compile_import file, aliases
saved_index = @index
saved_block = @block
+ saved_string = @string
+ saved_input_length = @input_length
old_filename = @filename
- @filename = file+'.cql'
+ @filename = file+'.cql' # REVISIT: Use File.dirname(@filename)+@filename ?
+ # REVISIT: Save and use another @vocabulary for this file?
File.open(@filename) do |f|
ok = parse_all(f.read, nil, &@block)
end
rescue => e
@@ -81,9 +108,11 @@
ne.set_backtrace(e.backtrace)
raise ne
ensure
@block = saved_block
@index = saved_index
+ @input_length = saved_input_length
+ @string = saved_string
@filename = old_filename
nil
end
def compile_definition ast