1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
package bjc.rgens.parser;
import bjc.utils.esodata.MapSet;
import bjc.utils.data.IPair;
import bjc.utils.data.Pair;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import static bjc.rgens.parser.RGrammarLogging.*;
/*
* The current state during generation.
*
*/
public class GenerationState {
/** The current string. */
public StringBuilder contents;
/** The RNG. */
public Random rnd;
/** The current grammar. */
public RGrammar gram;
/** The rules of the grammar. */
private Map<String, Rule> rules;
/** The rules imported from other grammars. */
private Map<String, Rule> importRules;
/** The current set of variables. */
private MapSet<String, String> vars;
private MapSet<String, Rule> rlVars;
private static final Random BASE = new Random();
/**
* Create a new generation state.
*
* @param cont
* The string being generated.
*
* @param rand
* The RNG to use.
*
* @param vs
* The variables to use.
*/
public GenerationState(StringBuilder cont, Random rand, Map<String, String> vs,
Map<String, Rule> rvs, RGrammar gram) {
vars = new MapSet<>();
rlVars = new MapSet<>();
contents = cont;
rnd = rand;
vars.setPutMap(gram.name, vs);
rlVars.setPutMap(gram.name, rvs);
this.gram = gram;
this.rules = gram.getRules();
this.importRules = gram.getImportRules();
}
public static GenerationState fromGrammar(RGrammar gram) {
return fromGrammar(BASE, gram);
}
public static GenerationState fromGrammar(Random rand, RGrammar gram) {
return new GenerationState(new StringBuilder(), rand, new HashMap<>(), new HashMap<>(), gram);
}
public void swapGrammar(RGrammar gram) {
if(this.gram == gram) return;
this.gram = gram;
rules = gram.getRules();
importRules = gram.getImportRules();
vars.setCreateMap(gram.name);
rlVars.setCreateMap(gram.name);
}
public GenerationState newBuf() {
return new GenerationState(new StringBuilder(), rnd, vars, rlVars, gram);
}
/*
* @TODO 6/5/18 Ben Culkin :ImportRefactor
*
* Change this so that imports in almost all cases have to specify where
* they are importing the rule from, so as to make it clear which rules
* are imported, and which aren't
*/
public Rule findRule(String ruleName, boolean allowImports) {
if(rules.containsKey(ruleName)) {
return rules.get(ruleName);
}
if(allowImports) return findImport(ruleName);
return null;
}
public Rule findImport(String ruleName) {
if(importRules.containsKey(ruleName)) {
return importRules.get(ruleName);
}
return null;
}
public void defineVar(String name, String val) {
if(vars.containsKey(name))
warn("Shadowing variable %s with value %s (old value %s)", name, vars.get(name), val);
vars.put(name, val);
}
public void defineRuleVar(String name, Rule rle) {
if(rlVars.containsKey(name))
warn("Shadowing rule variable %s with value %s (old value %s)", name, rlVars.get(name), rle);
rlVars.put(name, rle);
}
public String findVar(String name, GenerationState stat) {
if(!vars.containsKey(name))
throw new GrammarException(String.format("Variable %s not defined", name));
return vars.get(name);
}
public Rule findRuleVar(String name, GenerationState stat) {
if(!rlVars.containsKey(name))
throw new GrammarException(String.format("Rule variable %s not defined", name));
return rlVars.get(name);
}
}
|