@@ -264,3 +264,103 @@ TEST(parser, Parser2) {
264264
265265 ASSERT_TRUE (pars.IsComplete ());
266266}
267+
268+ TEST (parser, Parser3) {
269+ /* *
270+ * Grammar:
271+ * S -> Aa
272+ * A -> BD
273+ * B -> b | EPSILON
274+ * D -> d | EPSILON
275+ */
276+ grammar::Production p1;
277+ p1.SetParent (" S" );
278+ p1.SetRules ({grammar::Rule ({" A" , " a" })});
279+ grammar::Production p2;
280+ p2.SetParent (" A" );
281+ p2.SetRules ({grammar::Rule ({" B" , " D" })});
282+ grammar::Production p3;
283+ p3.SetParent (" B" );
284+ p3.SetRules ({grammar::Rule ({" b" }), grammar::Rule ({grammar::EPSILON})});
285+ grammar::Production p4;
286+ p4.SetParent (" D" );
287+ p4.SetRules ({grammar::Rule ({" d" }), grammar::Rule ({grammar::EPSILON})});
288+
289+ grammar::Productions grammar = {p1, p2, p3, p4};
290+
291+ auto nullables = utils::CalcNullables (grammar);
292+ auto firsts = utils::CalcFirsts (grammar, nullables);
293+ auto follows = utils::CalcFollows (grammar, firsts, nullables, " S" );
294+
295+ std::vector<std::string> terminals = {" a" , " b" , " d" };
296+ std::vector<std::string> non_terminals = {" S" , " A" , " B" , " D" };
297+
298+ ParsingTable table = ParsingTable (terminals, non_terminals);
299+ table.SetFirsts (firsts);
300+ table.SetFollows (follows);
301+ table.SetProductions (grammar);
302+ table.BuildTable ();
303+
304+ Parser pars = Parser ();
305+
306+ std::vector<std::string> input = {" b" , " d" , " a" };
307+ pars.SetInputString (input);
308+ pars.SetStartSymbol (" S" );
309+ pars.SetParsingTable (table);
310+
311+ while (!pars.IsComplete ()) {
312+ pars.ParseNextStep ();
313+ }
314+
315+ pars.BuildParseTree ();
316+ auto tree = pars.GetParseTree ();
317+ ASSERT_EQ (tree.dump (), " {\" S\" :{\" A\" :{\" B\" :{\" b\" :null},\" D\" :{\" d\" :null}},\" a\" :null}}" );
318+ }
319+
320+ TEST (parser, Parser4) {
321+ /* *
322+ * Grammar:
323+ * S -> ABA
324+ * A -> a
325+ * B -> b
326+ */
327+ grammar::Production p1;
328+ p1.SetParent (" S" );
329+ p1.SetRules ({grammar::Rule ({" A" , " B" , " A" })});
330+ grammar::Production p2;
331+ p2.SetParent (" A" );
332+ p2.SetRules ({grammar::Rule ({" a" })});
333+ grammar::Production p3;
334+ p3.SetParent (" B" );
335+ p3.SetRules ({grammar::Rule ({" b" })});
336+
337+ grammar::Productions grammar = {p1, p2, p3};
338+
339+ auto nullables = utils::CalcNullables (grammar);
340+ auto firsts = utils::CalcFirsts (grammar, nullables);
341+ auto follows = utils::CalcFollows (grammar, firsts, nullables, " S" );
342+
343+ std::vector<std::string> terminals = {" a" , " b" };
344+ std::vector<std::string> non_terminals = {" S" , " A" , " B" };
345+
346+ ParsingTable table = ParsingTable (terminals, non_terminals);
347+ table.SetFirsts (firsts);
348+ table.SetFollows (follows);
349+ table.SetProductions (grammar);
350+ table.BuildTable ();
351+
352+ Parser pars = Parser ();
353+
354+ std::vector<std::string> input = {" a" , " b" , " a" };
355+ pars.SetInputString (input);
356+ pars.SetStartSymbol (" S" );
357+ pars.SetParsingTable (table);
358+
359+ while (!pars.IsComplete ()) {
360+ pars.ParseNextStep ();
361+ }
362+
363+ pars.BuildParseTree ();
364+ auto tree = pars.GetParseTree ();
365+ ASSERT_EQ (tree.dump (), " {\" S\" :{\" A\" :{\" a\" :null},\" B\" :{\" b\" :null},\" A_1\" :{\" a\" :null}}}" );
366+ }
0 commit comments