Synthia
Generic and flexible data structure generator
GrammarSentence.java
Go to the documentation of this file.
1 /*
2  Synthia, a data structure generator
3  Copyright (C) 2019-2020 Laboratoire d'informatique formelle
4  Université du Québec à Chicoutimi, Canada
5 
6  This program is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 package ca.uqac.lif.synthia.grammar;
20 
21 import ca.uqac.lif.bullwinkle.*;
22 import ca.uqac.lif.synthia.Picker;
24 
25 import java.util.List;
26 
27 /**
28  * Picker that generates sentences from a format grammar. The picker's constructor
29  * takes as input an instance of a parser from the
30  * <a href="https://github.com/sylvainhalle/Bullwinkle">Bullwinkle</a> library,
31  * which is defined with respect to an underlying BNF grammar.
32  * Each time its {@link #pick()} method is called, the picker starts from the
33  * initial symbol of the grammar and randomly selects one of the rule's cases; it
34  * recursively expands this case until the expression is only composed of terminal
35  * symbols, and returns that expression.
36  *
37  * @ingroup API
38  */
39 public class GrammarSentence implements Picker<String>
40 {
41  /**
42  * The character used to separate the tokens
43  */
44  protected static final transient String SPACE = " ";
45 
46  /**
47  * The parser whose grammar will be used to generate expressions
48  */
49  /*@ non_null @*/ protected BnfParser m_parser;
50 
51  /**
52  * A picker used to choose the cases from the grammar rules
53  * to expand
54  */
55  /*@ non_null @*/ protected RandomInteger m_indexPicker;
56 
57  /**
58  * Creates a new instance of the picker
59  * @param parser The parser whose grammar will be used to generate expressions
60  * @param picker A picker used to choose the cases from the grammar rules
61  * to expand
62  */
63  public GrammarSentence(/*@ non_null @*/ BnfParser parser, /*@ non_null @*/ RandomInteger picker)
64  {
65  super();
66  m_parser = parser;
67  m_indexPicker = picker;
68  }
69 
70  @Override
71  public void reset()
72  {
74  }
75 
76  @Override
77  public String pick()
78  {
79  return pickRecursive(m_parser.getStartRule());
80  }
81 
82  /**
83  * Recursively expands a non-terminal symbol from the grammar. The
84  * recursion stops when it reaches a terminal symbol.
85  * @param rule The rule to expand
86  * @return The resulting expression
87  */
88  protected String pickRecursive(BnfRule rule)
89  {
90  List<TokenString> alternatives = rule.getAlternatives();
91  int chosen_index = m_indexPicker.setInterval(0,alternatives.size()).pick();
92  TokenString chosen_string = alternatives.get(chosen_index);
93  StringBuilder out = new StringBuilder();
94  for (Token t : chosen_string)
95  {
96  if (t instanceof StringTerminalToken)
97  {
98  out.append(t.getName()).append(SPACE);
99  }
100  else if (t instanceof NumberTerminalToken)
101  {
102  out.append(t.getName()).append(SPACE);
103  }
104  else if (t instanceof RegexTerminalToken)
105  {
106  out.append(t.getName());
107  }
108  else if (t instanceof EpsilonTerminalToken)
109  {
110  // Nothing to add
111  }
112  else if (t instanceof TerminalToken)
113  {
114  out.append(t.getName()).append(SPACE);
115  }
116  if (t instanceof NonTerminalToken)
117  {
118  BnfRule child_rule = m_parser.getRule(t.getName());
119  if (child_rule != null)
120  {
121  out.append(pickRecursive(child_rule));
122  }
123  }
124  }
125  return out.toString();
126  }
127 
128  @Override
129  public GrammarSentence duplicate(boolean with_state)
130  {
131  return new GrammarSentence(m_parser, m_indexPicker.duplicate(with_state));
132  }
133 }
ca.uqac.lif.synthia.Picker
Picks an object.
Definition: Picker.java:36
ca.uqac.lif.synthia.grammar.GrammarSentence.GrammarSentence
GrammarSentence(BnfParser parser, RandomInteger picker)
Creates a new instance of the picker.
Definition: GrammarSentence.java:63
ca.uqac
ca.uqac.lif.synthia.random
Pickers that produce pseudo-random objects such as numbers.
Definition: AffineTransform.java:19
ca.uqac.lif.synthia
Definition: Bounded.java:19
ca.uqac.lif.synthia.grammar.GrammarSentence.m_indexPicker
RandomInteger m_indexPicker
A picker used to choose the cases from the grammar rules to expand.
Definition: GrammarSentence.java:55
ca.uqac.lif.synthia.random.RandomInteger.setInterval
RandomInteger setInterval(int min, int max)
Sets the interval in which integers are picked.
Definition: RandomInteger.java:84
ca.uqac.lif
ca.uqac.lif.synthia.grammar.GrammarSentence.m_parser
BnfParser m_parser
The parser whose grammar will be used to generate expressions.
Definition: GrammarSentence.java:49
ca.uqac.lif.synthia.random.RandomPicker.reset
void reset()
Puts the picker back into its initial state.
Definition: RandomPicker.java:68
ca.uqac.lif.synthia.random.RandomInteger
Picks an integer uniformly in an interval.
Definition: RandomInteger.java:31
ca.uqac.lif.synthia.random.RandomInteger.pick
Integer pick()
Picks a random integer.
Definition: RandomInteger.java:118
ca
ca.uqac.lif.synthia.random.RandomInteger.duplicate
RandomInteger duplicate(boolean with_state)
Creates a copy of the RandomInteger picker.
Definition: RandomInteger.java:133
ca.uqac.lif.synthia.grammar.GrammarSentence.duplicate
GrammarSentence duplicate(boolean with_state)
Creates a copy of the picker.
Definition: GrammarSentence.java:129
ca.uqac.lif.synthia.grammar.GrammarSentence.reset
void reset()
Puts the picker back into its initial state.
Definition: GrammarSentence.java:71
ca.uqac.lif.synthia.grammar.GrammarSentence.pick
String pick()
Picks an object.
Definition: GrammarSentence.java:77
ca.uqac.lif.synthia.grammar.GrammarSentence
Picker that generates sentences from a format grammar.
Definition: GrammarSentence.java:39
ca.uqac.lif.synthia.grammar.GrammarSentence.pickRecursive
String pickRecursive(BnfRule rule)
Recursively expands a non-terminal symbol from the grammar.
Definition: GrammarSentence.java:88
ca.uqac.lif.synthia.grammar.GrammarSentence.SPACE
static final transient String SPACE
The character used to separate the tokens.
Definition: GrammarSentence.java:44