Class: Dendroid::GrmDSL::BaseGrmBuilder
- Inherits:
-
Object
- Object
- Dendroid::GrmDSL::BaseGrmBuilder
- Defined in:
- lib/dendroid/grm_dsl/base_grm_builder.rb
Overview
Builder GoF pattern: Builder builds a complex object.
here the builder creates a grammar from simpler objects
(symbols and production rules)
and using a step by step approach.
Instance Attribute Summary collapse
-
#rules ⇒ Array<Dendroid::Syntax::Rule>
readonly
The list of rules of the grammar.
-
#state ⇒ Symbol
readonly
One of: :declaring, :building, :complete.
-
#symbols ⇒ Hash{String, Dendroid::Syntax::GrmSymbol}
readonly
The mapping of grammar symbol names to the matching grammar symbol object.
Instance Method Summary collapse
-
#declare_terminals(*terminalSymbols) ⇒ void
Add the given terminal symbols to the grammar of the language.
-
#grammar ⇒ Dendroid::Syntax::Grammar
Generate the grammar according to the specifications.
-
#grammar_complete! ⇒ Object
A method used to notify the builder that the grammar is complete (i.e. all rules were entered).
-
#initialize(&aBlock) ⇒ BaseGrmBuilder
constructor
Creates a new grammar builder object.
-
#rule(productionRuleRepr) ⇒ Dendroid::Syntax::Rule
Add a production rule in the grammar given one key-value pair of the form: String => String.
Constructor Details
#initialize(&aBlock) ⇒ BaseGrmBuilder
Creates a new grammar builder object.
40 41 42 43 44 45 46 47 48 49 |
# File 'lib/dendroid/grm_dsl/base_grm_builder.rb', line 40 def initialize(&aBlock) @symbols = {} @rules = [] @state = :declaring return unless block_given? instance_exec(&aBlock) grammar_complete! end |
Instance Attribute Details
#rules ⇒ Array<Dendroid::Syntax::Rule> (readonly)
Returns The list of rules of the grammar.
27 28 29 |
# File 'lib/dendroid/grm_dsl/base_grm_builder.rb', line 27 def rules @rules end |
#state ⇒ Symbol (readonly)
Returns one of: :declaring, :building, :complete.
20 21 22 |
# File 'lib/dendroid/grm_dsl/base_grm_builder.rb', line 20 def state @state end |
#symbols ⇒ Hash{String, Dendroid::Syntax::GrmSymbol} (readonly)
Returns The mapping of grammar symbol names to the matching grammar symbol object.
24 25 26 |
# File 'lib/dendroid/grm_dsl/base_grm_builder.rb', line 24 def symbols @symbols end |
Instance Method Details
#declare_terminals(*terminalSymbols) ⇒ void
This method returns an undefined value.
Add the given terminal symbols to the grammar of the language
54 55 56 57 58 59 60 |
# File 'lib/dendroid/grm_dsl/base_grm_builder.rb', line 54 def declare_terminals(*terminalSymbols) err_msg = "Terminal symbols may only be declared in state :declaring, current state is: #{state}" raise StandardError, err_msg unless state == :declaring new_symbs = build_symbols(Dendroid::Syntax::Terminal, terminalSymbols) symbols.merge!(new_symbs) end |
#grammar ⇒ Dendroid::Syntax::Grammar
Generate the grammar according to the specifications.
110 111 112 113 114 115 116 |
# File 'lib/dendroid/grm_dsl/base_grm_builder.rb', line 110 def grammar terminals = symbols.values.select(&:terminal?) grm = Dendroid::Syntax::Grammar.new(terminals) rules.each { |prod| grm.add_rule(prod) } grm.complete! grm end |
#grammar_complete! ⇒ Object
A method used to notify the builder that the grammar is complete
(i.e. all rules were entered).
104 105 106 |
# File 'lib/dendroid/grm_dsl/base_grm_builder.rb', line 104 def grammar_complete! @state = :complete end |
#rule(productionRuleRepr) ⇒ Dendroid::Syntax::Rule
Add a production rule in the grammar given one key-value pair of the form: String => String.
Where the key is the name of the non-terminal appearing in the
left side of the rule.
When the value is a String, it is a sequence of grammar symbol names separated by space.
When the value is an array of String, the elements represent an alternative rhs
The rule is created and inserted in the grammar.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/dendroid/grm_dsl/base_grm_builder.rb', line 75 def rule(productionRuleRepr) raise StandardError, 'Cannot add a production rule in state :complete' if state == :complete @state = :building return nil unless productionRuleRepr.is_a?(Hash) head_name = productionRuleRepr.keys.first if symbols.include? head_name err_msg = "Terminal symbol '#{head_name}' may not be on left-side of a rule." raise StandardError, err_msg if symbols[head_name].is_a?(Dendroid::Syntax::Terminal) else symbols.merge!(build_symbols(Dendroid::Syntax::NonTerminal, [head_name])) end lhs = symbols[head_name] raw_rhs = productionRuleRepr.values.first if raw_rhs.is_a? String new_prod = Dendroid::Syntax::Production.new(lhs, build_symbol_seq(raw_rhs)) else rhs = raw_rhs.map { |raw| build_symbol_seq(raw) } new_prod = Dendroid::Syntax::Choice.new(lhs, rhs) end rules << new_prod new_prod end |