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
|
package bjc.rgens.parser.elements;
import java.util.List;
import bjc.rgens.parser.GenerationState;
import bjc.rgens.parser.GrammarException;
import bjc.rgens.parser.RGrammar;
import bjc.rgens.parser.Rule;
import bjc.rgens.parser.elements.vars.VariableElement;
/**
* Case element which references a rule.
*
* @author Ben Culkin
*
*/
public class RuleCaseElement extends CaseElement {
/**
* The elements for this rule.
*/
public List<VariableElement> elements;
/**
* Create a new case element to reference a rule.
*
* @param vl
* The text of the reference.
*/
public RuleCaseElement(String vl) {
super(true);
this.elements = VariableElement.parseElementString(vl);
}
/**
* Create a new case element to reference a rule.
*
* @param vl
* The text of the reference.
* @param elements
* The elements of the reference.
*/
public RuleCaseElement(String vl, List<VariableElement> elements) {
super(true);
this.elements = elements;
}
@Override
public void generate(GenerationState state) {
GenerationState newState = state.newBuf();
boolean inName = false;
for (VariableElement elm : elements) {
elm.generate(newState);
if (inName == false)
inName = elm.forbidSpaces;
}
String body = newState.getContents();
if (inName) {
doGenerate(String.format("[%s]", body), state);
} else {
state.appendContents(body);
}
}
/**
* Do the generation of a rule element.
*
* @param acName
* The name of the rule to generation.
* @param state
* The generation state.
*/
protected void doGenerate(String acName, GenerationState state) {
GenerationState newState = state.newBuf();
Rule rl;
String actName = acName;
if (actName.startsWith("[^")) {
actName = "[" + actName.substring(2);
rl = state.findImport(actName);
} else {
rl = state.findRule(actName, true);
}
if (rl != null) {
RGrammar destGrammar = rl.belongsTo;
newState.swapGrammar(destGrammar);
/*
* Don't postprocess the string, we should only do that once.
*/
String res = destGrammar.generate(actName, newState, false);
newState.setContents(res);
} else {
/*
* @TODO 5/29/18 Ben Culkin :RuleSuggesting
*
* Re-get this working again.
*/
/*
* if (ruleSearcher != null) { Set<Match<? extends String>> results =
* ruleSearcher.search(actName, MAX_DISTANCE);
*
* String[] resArray = results.stream().map(Match::getMatch).toArray((i) ->
* new String[i]);
*
* String msg = String.format("No rule '%s' defined (perhaps you meant %s?)",
* actName, StringUtils.toEnglishList(resArray, false));
*
* throw new GrammarException(msg); }
*/
String msg = String.format("No rule '%s' defined", actName);
throw new GrammarException(msg);
}
String res = newState.getContents();
if (actName.contains("+")) {
/* Rule names with pluses in them get space-flattened */
state.appendContents(res.replaceAll("\\s+", ""));
} else {
state.appendContents(res);
}
}
}
|