@Before public void init() { Nonterminal X = Nonterminal.withName("X"); Nonterminal A = Nonterminal.withName("A"); Nonterminal B = Nonterminal.withName("B"); Nonterminal C = Nonterminal.withName("C"); Rule r1 = Rule.withHead(X) .addSymbol(Nonterminal.builder(A).setLabel("a").build()) .addSymbol( Star.builder( Sequence.builder( Code.code( Nonterminal.builder(B) .addPreCondition(predicate(equal(rExt("a"), lExt("b")))) .build(), stat(println(lExt("b")))), Code.code( Nonterminal.builder(C).setLabel("b").build(), stat(println(var("b"))))) .build()) .setLabel("b") .build()) .build(); Rule r2 = Rule.withHead(A).addSymbol(Terminal.from(Character.from('a'))).build(); Rule r3 = Rule.withHead(B).addSymbol(Terminal.from(Character.from('b'))).build(); Rule r4 = Rule.withHead(C).addSymbol(Terminal.from(Character.from('c'))).build(); grammar = Grammar.builder().addRules(r1, r2, r3, r4).build(); }
@Before public void init() { Nonterminal S = Nonterminal.withName("S"); Nonterminal E = Nonterminal.builder("E").addParameters("l", "r").build(); Character z = Character.from('z'); Character w = Character.from('w'); Rule r0 = Rule.withHead(S) .addSymbol(Nonterminal.builder(E).apply(integer(0), integer(0)).build()) .build(); Rule r1_1 = Rule.withHead(E) .addSymbol( Nonterminal.builder(E) .apply(integer(5), var("r")) .addPreCondition(predicate(greaterEq(integer(5), var("r")))) .build()) .addSymbol(z) .build(); Rule r1_2 = Rule.withHead(E) .addSymbol( Character.builder('x') .addPreCondition(predicate(greaterEq(integer(4), var("l")))) .build()) .addSymbol(Nonterminal.builder(E).apply(var("l"), integer(4)).build()) .build(); Rule r1_3 = Rule.withHead(E) .addSymbol( Nonterminal.builder(E) .apply(integer(3), integer(0)) .addPreCondition(predicate(greaterEq(integer(3), var("r")))) .build()) .addSymbol(w) .build(); Rule r1_4 = Rule.withHead(E) .addSymbol( Character.builder('y') .addPreCondition(predicate(greaterEq(integer(2), var("l")))) .build()) .addSymbol(Nonterminal.builder(E).apply(integer(0), integer(0)).build()) .build(); Rule r1_5 = Rule.withHead(E).addSymbol(Character.from('a')).build(); grammar = Grammar.builder().addRules(r0, r1_1, r1_2, r1_3, r1_4, r1_5).build(); }
@Test public void test() { Grammar grammar = Grammar.builder() // $default$ ::= {UNDEFINED,-1,NON_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("$default$").build()) .setLayoutStrategy(NO_LAYOUT) .setRecursion(Recursion.NON_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(-1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false)) .build()) // E ::= ('-') E {UNDEFINED,1,RIGHT_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("E").build()) .addSymbol( Terminal.builder(Sequence.builder(Character.builder(45).build()).build()) .build()) .addSymbol(Nonterminal.builder("E").build()) .setRecursion(Recursion.RIGHT_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, 1, true, false, false, false)) .build()) // E ::= ('a') {UNDEFINED,-1,NON_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("E").build()) .addSymbol( Terminal.builder(Sequence.builder(Character.builder(97).build()).build()) .build()) .setRecursion(Recursion.NON_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(-1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, 1, true, false, false, false)) .build()) // E ::= E ('^') E {LEFT,2,LEFT_RIGHT_REC} PREC(2,2) .addRule( Rule.withHead(Nonterminal.builder("E").build()) .addSymbol(Nonterminal.builder("E").build()) .addSymbol( Terminal.builder(Sequence.builder(Character.builder(94).build()).build()) .build()) .addSymbol(Nonterminal.builder("E").build()) .setRecursion(Recursion.LEFT_RIGHT_REC) .setAssociativity(Associativity.LEFT) .setPrecedence(2) .setPrecedenceLevel(PrecedenceLevel.from(2, 2, -1, false, false, true, false)) .build()) // E ::= E ('*') E {UNDEFINED,3,LEFT_RIGHT_REC} PREC(3,3) .addRule( Rule.withHead(Nonterminal.builder("E").build()) .addSymbol(Nonterminal.builder("E").build()) .addSymbol( Terminal.builder(Sequence.builder(Character.builder(42).build()).build()) .build()) .addSymbol(Nonterminal.builder("E").build()) .setRecursion(Recursion.LEFT_RIGHT_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(3) .setPrecedenceLevel(PrecedenceLevel.from(3, 3, 3, false, false, true, false)) .build()) // S ::= E {UNDEFINED,-1,NON_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("S").build()) .addSymbol(Nonterminal.builder("E").build()) .setRecursion(Recursion.NON_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(-1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false)) .build()) .build(); // grammar = new EBNFToBNF().transform(grammar); System.out.println(grammar); grammar = new DesugarPrecedenceAndAssociativity().transform(grammar); System.out.println(grammar.toStringWithOrderByPrecedence()); Input input = Input.fromString("a*-a^a"); GrammarGraph graph = GrammarGraph.from(grammar, input, Configuration.DEFAULT); // Visualization.generateGrammarGraph("test/org/iguana/parser/datadependent/precedence/", // graph); ParseResult result = Iguana.parse(input, graph, Nonterminal.withName("S")); Assert.assertTrue(result.isParseSuccess()); // Visualization.generateSPPFGraph("test/org/iguana/parser/datadependent/precedence/", // result.asParseSuccess().getSPPFNode(), input); Assert.assertEquals(0, result.asParseSuccess().getStatistics().getCountAmbiguousNodes()); }
/** E ::= E '*' E | E '+' E | 'a' */ public class Test19 { static Nonterminal E = Nonterminal.withName("E"); static org.iguana.grammar.symbol.Character a = Character.from('a'); static Character plus = Character.from('+'); static Character star = Character.from('*'); static Rule r1 = Rule.withHead(E).addSymbols(E, star, E).build(); static Rule r2 = Rule.withHead(E).addSymbols(E, plus, E).build(); static Rule r3 = Rule.withHead(E).addSymbols(a).build(); public static Grammar grammar = Grammar.builder().addRules(r1, r2, r3).build(); private static Nonterminal startSymbol = E; private static Input input1 = Input.fromString("a+a"); private static Input input2 = Input.fromString("a+a*a"); private static Input input3 = Input.fromString("a+a*a+a*a"); @Test public void testParser1() { GrammarGraph graph = GrammarGraph.from(grammar, input1); ParseResult result = Iguana.parse(input1, graph, startSymbol); assertTrue(result.isParseSuccess()); assertEquals(getParseResult1(graph), result); assertEquals(getTree1(), result.asParseSuccess().getTree()); } @Test public void testParser2() { GrammarGraph graph = GrammarGraph.from(grammar, input2); ParseResult result = Iguana.parse(input2, graph, startSymbol); assertTrue(result.isParseSuccess()); assertEquals(getParseResult2(graph), result); assertEquals(getTree2(), result.asParseSuccess().getTree()); } @Test public void testParser3() { GrammarGraph graph = GrammarGraph.from(grammar, input3, Configuration.DEFAULT); ParseResult result = Iguana.parse(input3, graph, startSymbol); assertTrue(result.isParseSuccess()); assertEquals(getParseResult3(graph), result); assertEquals(getTree3(), result.asParseSuccess().getTree()); } private ParseSuccess getParseResult1(GrammarGraph registry) { ParseStatistics statistics = ParseStatistics.builder() .setDescriptorsCount(8) .setGSSNodesCount(2) .setGSSEdgesCount(5) .setNonterminalNodesCount(3) .setTerminalNodesCount(3) .setIntermediateNodesCount(2) .setPackedNodesCount(5) .setAmbiguousNodesCount(0) .build(); return new ParseSuccess(expectedSPPF1(registry), statistics, input1); } private NonterminalNode expectedSPPF1(GrammarGraph registry) { TerminalNode node0 = createTerminalNode(registry.getSlot("a"), 0, 1, input1); NonterminalNode node1 = createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node0, input1); TerminalNode node2 = createTerminalNode(registry.getSlot("+"), 1, 2, input1); IntermediateNode node3 = createIntermediateNode(registry.getSlot("E ::= E + . E"), node1, node2); TerminalNode node4 = createTerminalNode(registry.getSlot("a"), 2, 3, input1); NonterminalNode node5 = createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node4, input1); IntermediateNode node6 = createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node5); NonterminalNode node7 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node6, input1); return node7; } private Tree getTree1() { Tree t0 = createTerminal(0, 1, input1); Tree t1 = createRule(r3, list(t0), input1); Tree t2 = createTerminal(1, 2, input1); Tree t3 = createTerminal(2, 3, input1); Tree t4 = createRule(r3, list(t3), input1); Tree t5 = createRule(r2, list(t1, t2, t4), input1); return t5; } private ParseSuccess getParseResult2(GrammarGraph registry) { ParseStatistics statistics = ParseStatistics.builder() .setDescriptorsCount(16) .setGSSNodesCount(3) .setGSSEdgesCount(9) .setNonterminalNodesCount(6) .setTerminalNodesCount(5) .setIntermediateNodesCount(7) .setPackedNodesCount(14) .setAmbiguousNodesCount(1) .build(); return new ParseSuccess(expectedSPPF2(registry), statistics, input1); } private NonterminalNode expectedSPPF2(GrammarGraph registry) { TerminalNode node0 = createTerminalNode(registry.getSlot("a"), 0, 1, input2); NonterminalNode node1 = createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node0, input2); TerminalNode node2 = createTerminalNode(registry.getSlot("+"), 1, 2, input2); IntermediateNode node3 = createIntermediateNode(registry.getSlot("E ::= E + . E"), node1, node2); TerminalNode node4 = createTerminalNode(registry.getSlot("a"), 2, 3, input2); NonterminalNode node5 = createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node4, input2); TerminalNode node6 = createTerminalNode(registry.getSlot("*"), 3, 4, input2); IntermediateNode node7 = createIntermediateNode(registry.getSlot("E ::= E * . E"), node5, node6); TerminalNode node8 = createTerminalNode(registry.getSlot("a"), 4, 5, input2); NonterminalNode node9 = createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node8, input2); IntermediateNode node10 = createIntermediateNode(registry.getSlot("E ::= E * E ."), node7, node9); NonterminalNode node11 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E * E ."), node10, input2); IntermediateNode node12 = createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node11); IntermediateNode node13 = createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node5); NonterminalNode node14 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node13, input2); IntermediateNode node15 = createIntermediateNode(registry.getSlot("E ::= E * . E"), node14, node6); IntermediateNode node16 = createIntermediateNode(registry.getSlot("E ::= E * E ."), node15, node9); NonterminalNode node17 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node12, input2); node17.addPackedNode(registry.getSlot("E ::= E * E ."), node16); return node17; } private Tree getTree2() { Tree t0 = createTerminal(0, 1, input2); Tree t1 = createRule(r3, list(t0), input2); Tree t2 = createTerminal(1, 2, input2); Tree t3 = createTerminal(2, 3, input2); Tree t4 = createRule(r3, list(t3), input2); Tree t5 = createRule(r2, list(t1, t2, t4), input2); Tree t6 = createTerminal(3, 4, input2); Tree t7 = createTerminal(4, 5, input2); Tree t8 = createRule(r3, list(t7), input2); Tree t9 = createRule(r1, list(t4, t6, t8), input2); Tree t10 = createAmbiguity(set(createBranch(list(t5, t6, t8)), createBranch(list(t1, t2, t9)))); return t10; } private ParseSuccess getParseResult3(GrammarGraph registry) { ParseStatistics statistics = ParseStatistics.builder() .setDescriptorsCount(41) .setGSSNodesCount(5) .setGSSEdgesCount(20) .setNonterminalNodesCount(15) .setTerminalNodesCount(9) .setIntermediateNodesCount(26) .setPackedNodesCount(51) .setAmbiguousNodesCount(10) .build(); return new ParseSuccess(expectedSPPF3(registry), statistics, input1); } private NonterminalNode expectedSPPF3(GrammarGraph registry) { TerminalNode node0 = createTerminalNode(registry.getSlot("a"), 0, 1, input3); NonterminalNode node1 = createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node0, input3); TerminalNode node2 = createTerminalNode(registry.getSlot("+"), 1, 2, input3); IntermediateNode node3 = createIntermediateNode(registry.getSlot("E ::= E + . E"), node1, node2); TerminalNode node4 = createTerminalNode(registry.getSlot("a"), 2, 3, input3); NonterminalNode node5 = createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node4, input3); TerminalNode node6 = createTerminalNode(registry.getSlot("*"), 3, 4, input3); IntermediateNode node7 = createIntermediateNode(registry.getSlot("E ::= E * . E"), node5, node6); TerminalNode node8 = createTerminalNode(registry.getSlot("a"), 4, 5, input3); NonterminalNode node9 = createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node8, input3); IntermediateNode node10 = createIntermediateNode(registry.getSlot("E ::= E * E ."), node7, node9); NonterminalNode node11 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E * E ."), node10, input3); TerminalNode node12 = createTerminalNode(registry.getSlot("+"), 5, 6, input3); IntermediateNode node13 = createIntermediateNode(registry.getSlot("E ::= E + . E"), node11, node12); TerminalNode node14 = createTerminalNode(registry.getSlot("a"), 6, 7, input3); NonterminalNode node15 = createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node14, input3); IntermediateNode node16 = createIntermediateNode(registry.getSlot("E ::= E + E ."), node13, node15); IntermediateNode node17 = createIntermediateNode(registry.getSlot("E ::= E + . E"), node9, node12); IntermediateNode node18 = createIntermediateNode(registry.getSlot("E ::= E + E ."), node17, node15); NonterminalNode node19 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node18, input3); IntermediateNode node20 = createIntermediateNode(registry.getSlot("E ::= E * E ."), node7, node19); NonterminalNode node21 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node16, input3); node21.addPackedNode(registry.getSlot("E ::= E * E ."), node20); TerminalNode node22 = createTerminalNode(registry.getSlot("*"), 7, 8, input3); IntermediateNode node23 = createIntermediateNode(registry.getSlot("E ::= E * . E"), node21, node22); TerminalNode node24 = createTerminalNode(registry.getSlot("a"), 8, 9, input3); NonterminalNode node25 = createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node24, input3); IntermediateNode node26 = createIntermediateNode(registry.getSlot("E ::= E * . E"), node15, node22); IntermediateNode node27 = createIntermediateNode(registry.getSlot("E ::= E * E ."), node26, node25); NonterminalNode node28 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E * E ."), node27, input3); IntermediateNode node29 = createIntermediateNode(registry.getSlot("E ::= E + E ."), node17, node28); IntermediateNode node30 = createIntermediateNode(registry.getSlot("E ::= E * . E"), node19, node22); IntermediateNode node31 = createIntermediateNode(registry.getSlot("E ::= E * E ."), node30, node25); NonterminalNode node32 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node29, input3); node32.addPackedNode(registry.getSlot("E ::= E * E ."), node31); IntermediateNode node33 = createIntermediateNode(registry.getSlot("E ::= E * E ."), node23, node25); node33.addPackedNode(registry.getSlot("E ::= E * E ."), node7, node32); IntermediateNode node34 = createIntermediateNode(registry.getSlot("E ::= E + E ."), node13, node28); NonterminalNode node35 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E * E ."), node33, input3); node35.addPackedNode(registry.getSlot("E ::= E + E ."), node34); IntermediateNode node36 = createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node11); IntermediateNode node37 = createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node5); NonterminalNode node38 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node37, input3); IntermediateNode node39 = createIntermediateNode(registry.getSlot("E ::= E * . E"), node38, node6); IntermediateNode node40 = createIntermediateNode(registry.getSlot("E ::= E * E ."), node39, node9); NonterminalNode node41 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node36, input3); node41.addPackedNode(registry.getSlot("E ::= E * E ."), node40); IntermediateNode node42 = createIntermediateNode(registry.getSlot("E ::= E + . E"), node41, node12); IntermediateNode node43 = createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node35); node43.addPackedNode(registry.getSlot("E ::= E + E ."), node42, node28); IntermediateNode node44 = createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node21); node44.addPackedNode(registry.getSlot("E ::= E + E ."), node42, node15); IntermediateNode node45 = createIntermediateNode(registry.getSlot("E ::= E * E ."), node39, node19); NonterminalNode node46 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node44, input3); node46.addPackedNode(registry.getSlot("E ::= E * E ."), node45); IntermediateNode node47 = createIntermediateNode(registry.getSlot("E ::= E * . E"), node46, node22); IntermediateNode node48 = createIntermediateNode(registry.getSlot("E ::= E * E ."), node47, node25); node48.addPackedNode(registry.getSlot("E ::= E * E ."), node39, node32); NonterminalNode node49 = createNonterminalNode( registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node43, input3); node49.addPackedNode(registry.getSlot("E ::= E * E ."), node48); return node49; } private Tree getTree3() { Tree t0 = createTerminal(0, 1, input3); Tree t1 = createRule(r3, list(t0), input3); Tree t2 = createTerminal(1, 2, input3); Tree t3 = createTerminal(2, 3, input3); Tree t4 = createRule(r3, list(t3), input3); Tree t5 = createRule(r2, list(t1, t2, t4), input3); Tree t6 = createTerminal(3, 4, input3); Tree t7 = createTerminal(4, 5, input3); Tree t8 = createRule(r3, list(t7), input3); Tree t9 = createTerminal(5, 6, input3); Tree t10 = createTerminal(6, 7, input3); Tree t11 = createRule(r3, list(t10), input3); Tree t12 = createRule(r2, list(t8, t9, t11), input3); Tree t13 = createTerminal(7, 8, input3); Tree t14 = createTerminal(8, 9, input3); Tree t15 = createRule(r3, list(t14), input3); Tree t16 = createRule(r1, list(t11, t13, t15), input3); Tree t17 = createAmbiguity(set(createBranch(list(t12, t13, t15)), createBranch(list(t8, t9, t16)))); Tree t18 = createRule(r1, list(t4, t6, t8), input3); Tree t19 = createAmbiguity(set(createBranch(list(t4, t6, t12)), createBranch(list(t18, t9, t11)))); Tree t20 = createAmbiguity(set(createBranch(list(t1, t2, t18)), createBranch(list(t5, t6, t8)))); Tree t21 = createAmbiguity(set(createBranch(list(t20, t9, t11)), createBranch(list(t1, t2, t19)))); Tree t22 = createAmbiguity(set(createBranch(list(t21)), createBranch(list(t5, t6, t12)))); Tree t23 = createAmbiguity(set(createBranch(list(t5, t6, t17)), createBranch(list(t22, t13, t15)))); Tree t24 = createAmbiguity(set(createBranch(list(t19, t13, t15)), createBranch(list(t4, t6, t17)))); Tree t25 = createAmbiguity(set(createBranch(list(t24)), createBranch(list(t18, t9, t16)))); Tree t26 = createAmbiguity(set(createBranch(list(t20, t9, t16)), createBranch(list(t1, t2, t25)))); Tree t27 = createAmbiguity(set(createBranch(list(t26)), createBranch(list(t23)))); return t27; } }
@Test public void test() { Grammar grammar = Grammar.builder() // $default$ ::= {UNDEFINED,-1,NON_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("$default$").build()) .setLayoutStrategy(NO_LAYOUT) .setRecursion(Recursion.NON_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(-1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false)) .build()) // E ::= E ('+') E {LEFT,1,LEFT_RIGHT_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("E").build()) .addSymbol(Nonterminal.builder("E").build()) .addSymbol( Terminal.builder(Sequence.builder(Character.builder(43).build()).build()) .build()) .addSymbol(Nonterminal.builder("E").build()) .setRecursion(Recursion.LEFT_RIGHT_REC) .setAssociativity(Associativity.LEFT) .setPrecedence(1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false)) .build()) // E ::= ('a') {UNDEFINED,-1,NON_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("E").build()) .addSymbol( Terminal.builder(Sequence.builder(Character.builder(97).build()).build()) .build()) .setRecursion(Recursion.NON_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(-1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false)) .build()) // S ::= E {UNDEFINED,-1,NON_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("S").build()) .addSymbol(Nonterminal.builder("E").build()) .setRecursion(Recursion.NON_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(-1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false)) .build()) .build(); // grammar = new EBNFToBNF().transform(grammar); System.out.println(grammar); grammar = new DesugarPrecedenceAndAssociativity().transform(grammar); System.out.println(grammar.toStringWithOrderByPrecedence()); Input input = Input.fromString("a+a+a"); GrammarGraph graph = grammar.toGrammarGraph(input, Configuration.DEFAULT); // Visualization.generateGrammarGraph("/Users/anastasiaizmaylova/git/diguana/test/org/jgll/parser/datadependent/precedence/", graph); GLLParser parser = ParserFactory.getParser(Configuration.DEFAULT, input, grammar); ParseResult result = parser.parse(input, graph, Nonterminal.withName("S")); Assert.assertTrue(result.isParseSuccess()); // Visualization.generateSPPFGraph("/Users/anastasiaizmaylova/git/diguana/test/org/jgll/parser/datadependent/precedence/", // result.asParseSuccess().getRoot(), input); Assert.assertTrue(result.asParseSuccess().getStatistics().getCountAmbiguousNodes() == 0); }
@Test public void test() { Grammar grammar = Grammar.builder() .setLayout(Nonterminal.builder("L").build()) // $default$ ::= {UNDEFINED,-1,NON_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("$default$").build()) .setLayoutStrategy(NO_LAYOUT) .setRecursion(Recursion.NON_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(-1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false)) .build()) // L ::= (\u0009-\\u000A | \\u000D | \u0020)* !>> (\u0009-\\u000A | \\u000D | \u0020) // {UNDEFINED,-1,NON_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("L").build()) .addSymbol( Star.builder( Alt.builder( CharacterRange.builder(9, 10).build(), CharacterRange.builder(13, 13).build(), CharacterRange.builder(32, 32).build()) .build()) .addPostConditions( set( new RegularExpressionCondition( ConditionType.NOT_FOLLOW, Alt.builder( CharacterRange.builder(9, 10).build(), CharacterRange.builder(13, 13).build(), CharacterRange.builder(32, 32).build()) .build()))) .build()) .setLayoutStrategy(NO_LAYOUT) .setRecursion(Recursion.NON_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(-1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false)) .build()) // E ::= (i f) E (t h e n) E (e l s e) E {UNDEFINED,1,RIGHT_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("E").build()) .addSymbol( Terminal.builder( Sequence.builder( Character.builder(105).build(), Character.builder(102).build()) .build()) .build()) .addSymbol(Nonterminal.builder("E").build()) .addSymbol( Terminal.builder( Sequence.builder( Character.builder(116).build(), Character.builder(104).build(), Character.builder(101).build(), Character.builder(110).build()) .build()) .build()) .addSymbol(Nonterminal.builder("E").build()) .addSymbol( Terminal.builder( Sequence.builder( Character.builder(101).build(), Character.builder(108).build(), Character.builder(115).build(), Character.builder(101).build()) .build()) .build()) .addSymbol(Nonterminal.builder("E").build()) .setRecursion(Recursion.RIGHT_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, 1, true, false, false, false)) .build()) // E ::= (a) {UNDEFINED,-1,NON_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("E").build()) .addSymbol( Terminal.builder(Sequence.builder(Character.builder(97).build()).build()) .build()) .setRecursion(Recursion.NON_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(-1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, 1, true, false, false, false)) .build()) // E ::= E (+) E {LEFT,2,LEFT_RIGHT_REC} PREC(2,2) .addRule( Rule.withHead(Nonterminal.builder("E").build()) .addSymbol(Nonterminal.builder("E").build()) .addSymbol( Terminal.builder(Sequence.builder(Character.builder(43).build()).build()) .build()) .addSymbol(Nonterminal.builder("E").build()) .setRecursion(Recursion.LEFT_RIGHT_REC) .setAssociativity(Associativity.LEFT) .setPrecedence(2) .setPrecedenceLevel(PrecedenceLevel.from(2, 2, -1, false, false, true, false)) .build()) // S ::= E {UNDEFINED,-1,NON_REC} PREC(1,1) .addRule( Rule.withHead(Nonterminal.builder("S").build()) .addSymbol(Nonterminal.builder("E").build()) .setRecursion(Recursion.NON_REC) .setAssociativity(Associativity.UNDEFINED) .setPrecedence(-1) .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false)) .build()) .build(); grammar = new EBNFToBNF().transform(grammar); grammar = new DesugarPrecedenceAndAssociativity().transform(grammar); System.out.println(grammar.toStringWithOrderByPrecedence()); grammar = new LayoutWeaver().transform(grammar); Input input = Input.fromString("a + if a then a else a + a"); GrammarGraph graph = grammar.toGrammarGraph(input, Configuration.DEFAULT); // Visualization.generateGrammarGraph("/Users/anastasiaizmaylova/git/diguana/test/org/jgll/parser/datadependent/precedence/", graph); GLLParser parser = ParserFactory.getParser(Configuration.DEFAULT, input, grammar); ParseResult result = parser.parse(input, graph, Nonterminal.withName("S")); Assert.assertTrue(result.isParseSuccess()); Visualization.generateSPPFGraph( "/Users/anastasiaizmaylova/git/diguana/test/org/jgll/parser/datadependent/precedence/", result.asParseSuccess().getRoot(), input); Assert.assertTrue(result.asParseSuccess().getStatistics().getCountAmbiguousNodes() == 0); }