1 --[[--------------------------------------------------------------------
3 Gazelle: a system for building fast, reusable parsers
7 Routines that test the generation of IntFAs.
9 Copyright (c) 2008 Joshua Haberman. See LICENSE for details.
11 --------------------------------------------------------------------]]--
14 require
"bootstrap/rtn"
19 function assert_intfas(grammar_str
, ...)
20 local grammar
= parse_grammar(CharStream
:new(grammar_str
))
21 grammar
:assign_priorities()
22 grammar
:determinize_rtns()
23 grammar
:minimize_rtns()
24 compute_lookahead(grammar
, k
)
25 grammar
:generate_intfas()
27 local intfa_strings
= {...}
28 if #intfa_strings
~= grammar
.master_intfas
:count() then
29 error(string.format("Expected to get %d IntFAs but got %d instead",
30 #intfa_strings
, #grammar
.master_intfas
))
33 for i
, intfa_string
in pairs(intfa_strings
) do
34 local expected_intfa
= parse_intfa(intfa_string
)
35 local actual_intfa
= grammar
.master_intfas
:element_at(i
)
36 if not fa_isequal(expected_intfa
, actual_intfa
) then
37 local bad
= io
.open("bad.dot", "w")
38 bad
:write("digraph untitled {\n")
39 bad
:write(actual_intfa
:to_dot(" "))
43 local good
= io
.open("good.dot", "w")
44 good
:write("digraph untitled {\n")
45 good
:write(expected_intfa
:to_dot(" "))
49 os
.execute("dot -Tpng -o good.png good.dot")
50 os
.execute("dot -Tpng -o bad.png bad.dot")
52 error("GLAs were not equal: expected and actual are " ..
53 "in good.png and bad.png, respectively")
58 function parse_intfa(str
)
59 local stream
= CharStream
:new(str
)
60 stream
:ignore("whitespace")
61 local intfa
= fa
.RTN
:new()
62 local states
= {[1]=intfa
.start
}
63 while not stream
:eof() do
64 local statenum
= tonumber(stream
:consume_pattern("%d+"))
65 local state
= states
[statenum
]
67 error(string.format("IntFA refers to state %d before it is used as a target",
70 while stream
:lookahead(1) ~= ";" do
72 local term
= stream
:consume_pattern("%w"):byte()
74 local dest_state_num
= tonumber(stream
:consume_pattern("%d+"))
75 states
[dest_state_num
] = states
[dest_state_num
] or fa
.IntFAState
:new()
76 local dest_state
= states
[dest_state_num
]
77 state
:add_transition(term
, dest_state
)
78 if stream
:lookahead(1) == "(" then
80 dest_state
.final
= stream
:consume_pattern("%w+")
92 function TestSimple
:test1()
104 LuaUnit
:run(unpack(arg
))