require 'test/unit' require 'parse/grammar' include Parse::Grammar class UT_Parse_Grammar < Test::Unit::TestCase def test_01_Symbol s = Parse::Grammar::GrammarSymbol.new "name" assert_equal("name", s.name) assert_equal("name", s.inspect) assert_equal(s, s.to_grammar_symbol) end def test_02_Symbol_name_not_needed s = Parse::Grammar::GrammarSymbol.new assert_equal(nil, s.name) assert_equal(s, s.to_grammar_symbol) end def test_03_NonTerminal s = NonTerminal.new :name assert_equal(:name, s.name) assert_equal("name", s.inspect) assert_kind_of(Parse::Grammar::GrammarSymbol, s) assert_equal(s, s.to_grammar_symbol) end def test_04_Terminal s = Terminal.new assert_kind_of(Parse::Grammar::GrammarSymbol, s) end def test_05_Production p = Production.new(n = NonTerminal.new(:N), [t = Terminal.new(:T)]) assert_equal(n, p.symbol) assert_equal(t, p.rhs.first) assert_equal(t, p.right_hand_side.first) end def test_06_Production_short_hand p = Prod[n = NonTerminal.new(:N), [t = Terminal.new(:T)]] assert_equal(n, p.symbol) assert_equal(t, p.rhs.first) assert_equal(t, p.right_hand_side.first) p2 = Prod[:N, [t]] assert_equal("N", p2.symbol.inspect) end def test_07_nonterminal_equality n1 = NonTerminal.new(:N) n2 = NonTerminal.new(:N) assert(n1 == n2) assert(n2 == n1) end def test_08_Rule p1 = Prod[n = NonTerminal.new(:N), [Terminal.new(:T1)]] p2 = Prod[:N, [Terminal.new(:T2)]] r = Rule[p1] assert(n == r.symbol) assert_equal(1, r.productions.length) r.add_production p2 assert_equal(n, r.symbol) assert_equal(2, r.productions.length) assert_raises(ArgumentError) {r.add_production(Prod[:N2, [Terminal[:T3]]])} end def test_09_Grammar g = Grammar.new(:name => "Test Grammar 1", :author => "Robert") assert_kind_of(Grammar, g) assert_equal("Test Grammar 1", g.meta[:name]) assert_equal("Robert", g.meta[:author]) assert_equal(0, g.rules.length) assert_equal(0, g.nonterminals.length) assert_equal(0, g.terminals.length) assert_equal(0, g.symbols.length) g.add_rule(Rule[Prod[:N, [Terminal[:T1]]]]) assert_equal(1, g.rules.length) assert_equal(1, g.nonterminals.length) assert_equal(1, g.terminals.length) assert_equal(2, g.symbols.length) end def test_10_symbol_predicates nt = NonTerminal[:N] assert_equal(true, nt.nonterminal?) assert_equal(false, nt.terminal?) assert_equal(false, nt.action?) t = Terminal[:T] assert_equal(false, t.nonterminal?) assert_equal(true, t.terminal?) assert_equal(false, t.action?) a = Action[:A] assert_equal(false, a.nonterminal?) assert_equal(false, a.terminal?) assert_equal(true, a.action?) end class TestGrammar < Grammar r :S, [[:B]] r :B, [ [Terminal.new(:T1)], [Terminal.new(:T2), Terminal.new(:T3)], ] t :CT1, ["A"] end def test_11_embedded_grammar_def t = TestGrammar.new assert_equal(2, t.rules.length) assert_equal(:S, t.rules.first.symbol.name) assert_equal(1, t.rules.first.productions.length) assert_equal(:B, t.rules.last.symbol.name) assert_equal(2, t.rules.last.productions.length) assert_equal(:T1, t.rules.last.productions.first.rhs.first.name) assert_equal(:T2, t.rules.last.productions.last.rhs.first.name) assert_equal(:T3, t.rules.last.productions.last.rhs.last.name) assert_equal(1, t.complex_terminals.length) assert_equal(:CT1, t.complex_terminals.first.name) end TestDeepClone = Struct.new(:a) def test_12_deep_clone a = [1,2,3] t1 = TestDeepClone.new(a) t1a = t1.clone t1b = t1.deep_clone assert_equal(t1.a.object_id, t1a.a.object_id) assert_not_equal(t1.a.object_id, t1b.a.object_id) end def test_13_define_grammar_in_a_block g = Grammar.new do r :S, [["a", :B]] r :B, [["b"]] end assert_equal(2, g.nonterminals.length) end def test_14_extending_a_grammar_with_a_block g = TestGrammar.new do r :A, [["a"]] end # Two nonterminals in the original grammar and one new here => 3 assert_equal(3, g.nonterminals.length) end end