Class: JSGF::Grammar
- Inherits:
-
Object
- Object
- JSGF::Grammar
- Defined in:
- lib/jsgf/grammar.rb
Instance Attribute Summary collapse
-
#character_encoding ⇒ Object
readonly
Returns the value of attribute character_encoding.
-
#grammar_name ⇒ Object
readonly
Returns the value of attribute grammar_name.
-
#locale ⇒ Object
readonly
Returns the value of attribute locale.
-
#private_rules ⇒ Object
readonly
Returns the value of attribute private_rules.
-
#public_rules ⇒ Object
readonly
Returns the value of attribute public_rules.
- #roots ⇒ Object
- #rules ⇒ Object
- #version ⇒ Object
Class Method Summary collapse
-
.find_rule_names(rule) ⇒ Array
Expand the given rule and collect any references to other rules.
-
.roots(rules) ⇒ Array<Hash,Hash>
The set of root and non-root rules from the given set of rules.
Instance Method Summary collapse
-
#initialize(name: nil, character_encoding: nil, locale: nil, private_rules: {}, public_rules: {}, rules: nil, version: nil) ⇒ Grammar
constructor
A new instance of Grammar.
- #to_s ⇒ Object
-
#write(file) ⇒ Object
Write the Grammar to a file or an IO stream.
Constructor Details
#initialize(name: nil, character_encoding: nil, locale: nil, private_rules: {}, public_rules: {}, rules: nil, version: nil) ⇒ Grammar
Returns a new instance of Grammar.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/jsgf/grammar.rb', line 36 def initialize(name:nil, character_encoding:nil, locale:nil, private_rules:{}, public_rules:{}, rules:nil, version:nil) raise ArgumentError, "Grammar requires a name" unless name @character_encoding = character_encoding @locale = locale @grammar_name = name @version = version if rules and !rules.empty? @public_rules, @private_rules = ::JSGF::Grammar.roots(rules) else @private_rules = private_rules @public_rules = public_rules end end |
Instance Attribute Details
#character_encoding ⇒ Object (readonly)
Returns the value of attribute character_encoding.
5 6 7 |
# File 'lib/jsgf/grammar.rb', line 5 def character_encoding @character_encoding end |
#grammar_name ⇒ Object (readonly)
Returns the value of attribute grammar_name.
7 8 9 |
# File 'lib/jsgf/grammar.rb', line 7 def grammar_name @grammar_name end |
#locale ⇒ Object (readonly)
Returns the value of attribute locale.
6 7 8 |
# File 'lib/jsgf/grammar.rb', line 6 def locale @locale end |
#private_rules ⇒ Object (readonly)
Returns the value of attribute private_rules.
8 9 10 |
# File 'lib/jsgf/grammar.rb', line 8 def private_rules @private_rules end |
#public_rules ⇒ Object (readonly)
Returns the value of attribute public_rules.
9 10 11 |
# File 'lib/jsgf/grammar.rb', line 9 def public_rules @public_rules end |
#roots ⇒ Object
53 54 55 56 |
# File 'lib/jsgf/grammar.rb', line 53 def roots r = self.class.roots(public_rules).first r.empty? ? nil : r end |
#rules ⇒ Object
60 61 62 |
# File 'lib/jsgf/grammar.rb', line 60 def rules @public_rules.merge(@private_rules) end |
#version ⇒ Object
66 67 68 |
# File 'lib/jsgf/grammar.rb', line 66 def version @version end |
Class Method Details
.find_rule_names(rule) ⇒ Array
Expand the given rule and collect any references to other rules
25 26 27 28 29 30 31 32 33 34 |
# File 'lib/jsgf/grammar.rb', line 25 def self.find_rule_names(rule) case rule when Alternation, Array, Optional rule.flat_map {|a| find_rule_names(a) } when Hash rule[:name] else raise StandardError, "Unkown atom #{rule.class}" end end |
.roots(rules) ⇒ Array<Hash,Hash>
Returns the set of root and non-root rules from the given set of rules.
14 15 16 17 18 19 20 |
# File 'lib/jsgf/grammar.rb', line 14 def self.roots(rules) # Descend through the rule trees to see if they reference each other. # Root rules aren't referenced by any other rule. names = rules.flat_map {|(name,rule)| find_rule_names(rule)}.compact.uniq left, right = rules.partition {|name, rule| names.include?(name) } [Hash[right], Hash[left]] end |
Instance Method Details
#to_s ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/jsgf/grammar.rb', line 70 def to_s private_rule_array = @private_rules.map do |(name, rule)| atoms = rule.map {|a| unparse_atom(a) }.join(' ') "<#{name}> = #{atoms};" end public_rule_array = @public_rules.map do |(name, rule)| atoms = rule.map {|a| unparse_atom(a) }.join(' ') "public <#{name}> = #{atoms};" end [header, grammar_header, *public_rule_array, *private_rule_array].join("\n") end |
#write(file) ⇒ Object
Write the JSGF::Grammar to a file or an IO stream
85 86 87 88 89 90 91 |
# File 'lib/jsgf/grammar.rb', line 85 def write(file) if file.is_a?(String) File.write(file, self.to_s) else file.write(self.to_s) end end |