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
|
package bjc.rgens.parser.templates;
import bjc.rgens.parser.ConfigSet;
import bjc.rgens.parser.GenerationState;
import bjc.data.Tree;
import bjc.data.SimpleTree;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* Represents a grammar template.
*
* @author Ben Culkin
*/
public class GrammarTemplate {
/**
* The config set the template belongs to.
*/
public ConfigSet belongsTo;
/**
* The name of the template.
*/
public String name;
/**
* The elements in the template.
*/
public final List<TemplateElement> elements;
/**
* Whether or not to do spacing of elements.
*/
public boolean doSpacing = true;
/**
* Create a new grammar template.
*
* @param elements
* The elements that belong to the template.
*/
public GrammarTemplate(List<TemplateElement> elements) {
this.elements = elements;
}
/**
* Generate the template.
*
* @param state
* The state for generating a template.
*/
public void generate(GenerationState state) {
for(TemplateElement element : elements) {
element.generate(state);
if(doSpacing && element.spacing)
state.appendContents("\n");
}
}
/**
* Read a template from an input source.
*
* @param rdr
* The reader to get input from.
*
* @param errs
* The errors/information to generate during loading.
*
* @return The generated template.
*/
public static GrammarTemplate readTemplate(Reader rdr, Tree<String> errs) {
List<TemplateElement> elements = new ArrayList<>();
GrammarTemplate template = new GrammarTemplate(elements);
try (Scanner scn = new Scanner(rdr)) {
scn.useDelimiter("\\R");
int lno = 0;
while(scn.hasNextLine()) {
String ln = scn.nextLine();
lno += 1;
Tree<String> kid = new SimpleTree<>(String.format("INFO: Line %d", lno));
switch(ln.charAt(0)) {
case '#':
// Ignore comments
break;
case '/':
handlePragma(elements, template, ln.substring(1), kid);
break;
default:
handleLine(elements, template, ln, kid);
}
if (kid.size() > 0) {
errs.addChild(kid);
}
}
}
return template;
}
private static void handleLine(List<TemplateElement> elements, GrammarTemplate template, String ln, Tree<String> errs) {
if(ln.matches("^.*?\\$@.+?@\\$.*$")) {
/*
* Handle live templates
*/
elements.add(new LiveTemplateElement(ln, errs));
} else {
elements.add(new LiteralTemplateElement(ln, errs));
}
}
private static void handlePragma(List<TemplateElement> elements, GrammarTemplate template, String ln, Tree<String> errs) {
/*
* @TODO 2/8/2019 Ben Culkin :TemplatePragmas
* Implement template pragmas.
*
* Implement template pragmas. Mainly, this means that the 'choose'
* based ones need to be implemented based off of the provided sample
* template.
*/
errs.addChild("ERROR: Template pragmas are not yet implemented");
}
}
|