gherkin 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitattributes +1 -0
- data/History.txt +18 -0
- data/README.rdoc +4 -1
- data/Rakefile +4 -2
- data/VERSION.yml +1 -1
- data/bin/gherkin +1 -1
- data/dotnet/.gitignore +13 -0
- data/features/feature_parser.feature +22 -2
- data/features/native_lexer.feature +1 -1
- data/features/parser_with_native_lexer.feature +1 -1
- data/features/step_definitions/gherkin_steps.rb +2 -6
- data/features/step_definitions/pretty_printer_steps.rb +2 -3
- data/features/steps_parser.feature +1 -1
- data/gherkin.gemspec +53 -24
- data/java/Gherkin.iml +2 -4
- data/java/build.xml +3 -0
- data/java/src/gherkin/FixJava.java +6 -3
- data/java/src/gherkin/I18nLexer.java +48 -0
- data/java/src/gherkin/Listener.java +3 -1
- data/java/src/gherkin/Main.java +17 -0
- data/java/src/gherkin/Parser.java +9 -3
- data/java/src/gherkin/formatter/Argument.java +39 -0
- data/java/src/gherkin/formatter/ArgumentFormat.java +17 -0
- data/java/src/gherkin/formatter/Colors.java +7 -0
- data/java/src/gherkin/formatter/Formatter.java +15 -0
- data/java/src/gherkin/formatter/PrettyFormatter.java +219 -0
- data/java/src/gherkin/parser/StateMachineReader.java +8 -3
- data/java/test/gherkin/formatter/ArgumentTest.java +17 -0
- data/lib/gherkin/csharp_lexer.rb +15 -0
- data/lib/gherkin/format/argument.rb +35 -0
- data/lib/gherkin/format/monochrome_format.rb +9 -0
- data/lib/gherkin/i18n.rb +22 -0
- data/lib/gherkin/i18n.yml +34 -20
- data/lib/gherkin/i18n_lexer.rb +57 -13
- data/lib/gherkin/lexer.rb +9 -18
- data/lib/gherkin/parser.rb +3 -3
- data/lib/gherkin/parser/meta.txt +5 -4
- data/lib/gherkin/parser/root.txt +11 -9
- data/lib/gherkin/parser/steps.txt +4 -3
- data/lib/gherkin/rb_parser.rb +13 -5
- data/lib/gherkin/tools/colors.rb +119 -0
- data/lib/gherkin/tools/files.rb +6 -1
- data/lib/gherkin/tools/pretty_listener.rb +115 -23
- data/ragel/lexer.c.rl.erb +67 -51
- data/ragel/lexer.csharp.rl.erb +240 -0
- data/ragel/lexer.java.rl.erb +27 -18
- data/ragel/lexer.rb.rl.erb +17 -17
- data/ragel/lexer_common.rl.erb +8 -8
- data/spec/gherkin/c_lexer_spec.rb +4 -4
- data/spec/gherkin/csharp_lexer_spec.rb +20 -0
- data/spec/gherkin/fixtures/comments_in_table.feature +9 -0
- data/spec/gherkin/fixtures/complex.feature +2 -0
- data/spec/gherkin/fixtures/dos_line_endings.feature +45 -0
- data/spec/gherkin/fixtures/i18n_fr.feature +1 -0
- data/spec/gherkin/fixtures/i18n_no.feature +1 -0
- data/spec/gherkin/fixtures/i18n_zh-CN.feature +1 -0
- data/spec/gherkin/format/argument_spec.rb +28 -0
- data/spec/gherkin/i18n_lexer_spec.rb +4 -4
- data/spec/gherkin/i18n_spec.rb +31 -23
- data/spec/gherkin/java_lexer_spec.rb +4 -3
- data/spec/gherkin/parser_spec.rb +5 -0
- data/spec/gherkin/rb_lexer_spec.rb +4 -2
- data/spec/gherkin/sexp_recorder.rb +1 -1
- data/spec/gherkin/shared/lexer_spec.rb +169 -60
- data/spec/gherkin/shared/py_string_spec.rb +6 -0
- data/spec/gherkin/shared/row_spec.rb +107 -0
- data/spec/gherkin/shared/tags_spec.rb +1 -1
- data/spec/gherkin/tools/colors_spec.rb +19 -0
- data/spec/gherkin/tools/pretty_listener_spec.rb +147 -0
- data/spec/spec_helper.rb +31 -7
- data/tasks/compile.rake +81 -7
- data/tasks/ragel_task.rb +6 -4
- data/tasks/rspec.rake +2 -2
- metadata +104 -41
- data/lib/gherkin/java_lexer.rb +0 -10
- data/spec/gherkin/shared/table_spec.rb +0 -97
@@ -17,14 +17,17 @@ public class FixJava {
|
|
17
17
|
return sb.toString();
|
18
18
|
}
|
19
19
|
|
20
|
-
public static String
|
21
|
-
Reader
|
20
|
+
public static String readResource(String filePath) throws IOException {
|
21
|
+
Reader reader = new InputStreamReader(FixJava.class.getResourceAsStream(filePath));
|
22
|
+
return readReader(reader);
|
23
|
+
}
|
22
24
|
|
25
|
+
public static String readReader(Reader reader) throws IOException {
|
23
26
|
final char[] buffer = new char[0x10000];
|
24
27
|
StringBuilder sb = new StringBuilder();
|
25
28
|
int read;
|
26
29
|
do {
|
27
|
-
read =
|
30
|
+
read = reader.read(buffer, 0, buffer.length);
|
28
31
|
if (read > 0) {
|
29
32
|
sb.append(buffer, 0, read);
|
30
33
|
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
package gherkin;
|
2
|
+
|
3
|
+
import java.util.regex.Matcher;
|
4
|
+
import java.util.regex.Pattern;
|
5
|
+
|
6
|
+
public class I18nLexer implements Lexer {
|
7
|
+
private static final Pattern LANGUAGE_PATTERN = Pattern.compile("language\\s*:\\s*(.*)");
|
8
|
+
private final Listener listener;
|
9
|
+
private String i18nLanguage;
|
10
|
+
|
11
|
+
public I18nLexer(Listener listener) {
|
12
|
+
this.listener = listener;
|
13
|
+
}
|
14
|
+
|
15
|
+
/**
|
16
|
+
* @return the i18n language code from the previous scanned source.
|
17
|
+
*/
|
18
|
+
public String getI18nLanguage() {
|
19
|
+
return i18nLanguage;
|
20
|
+
}
|
21
|
+
|
22
|
+
public void scan(CharSequence source) {
|
23
|
+
createDelegate(source).scan(source);
|
24
|
+
}
|
25
|
+
|
26
|
+
private Lexer createDelegate(CharSequence source) {
|
27
|
+
i18nLanguage = lang(source);
|
28
|
+
String i18nLanguage = this.i18nLanguage.replaceAll("[\\s-]", "").toLowerCase();
|
29
|
+
String i18nLexerClassName = i18nLanguage.substring(0,1).toUpperCase() + i18nLanguage.substring(1);
|
30
|
+
String qualifiedI18nLexerClassName = "gherkin.lexer." + i18nLexerClassName;
|
31
|
+
try {
|
32
|
+
Class<?> delegateClass = Class.forName(qualifiedI18nLexerClassName);
|
33
|
+
return (Lexer) delegateClass.getConstructor(Listener.class).newInstance(listener);
|
34
|
+
} catch (Exception e) {
|
35
|
+
throw new RuntimeException("Couldn't load lexer class: " + qualifiedI18nLexerClassName, e);
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
private String lang(CharSequence source) {
|
40
|
+
String lineOne = source.toString().split("\\n")[0];
|
41
|
+
Matcher matcher = LANGUAGE_PATTERN.matcher(lineOne);
|
42
|
+
if(matcher.find()) {
|
43
|
+
return matcher.group(1);
|
44
|
+
} else {
|
45
|
+
return "en";
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
@@ -19,9 +19,11 @@ public interface Listener {
|
|
19
19
|
|
20
20
|
void step(String keyword, String name, int line);
|
21
21
|
|
22
|
-
void
|
22
|
+
void row(List<String> row, int line);
|
23
23
|
|
24
24
|
void py_string(String string, int line);
|
25
25
|
|
26
|
+
void eof();
|
27
|
+
|
26
28
|
void syntax_error(String state, String event, List<String> legalEvents, int line);
|
27
29
|
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
package gherkin;
|
2
|
+
|
3
|
+
import gherkin.formatter.PrettyFormatter;
|
4
|
+
|
5
|
+
import java.io.FileReader;
|
6
|
+
import java.io.IOException;
|
7
|
+
|
8
|
+
public class Main {
|
9
|
+
public static void main(String[] args) throws IOException {
|
10
|
+
Parser p = new Parser(new PrettyFormatter(System.out, true));
|
11
|
+
Lexer l = new I18nLexer(p);
|
12
|
+
|
13
|
+
CharSequence input = FixJava.readReader(new FileReader(args[0]));
|
14
|
+
l.scan(input);
|
15
|
+
}
|
16
|
+
|
17
|
+
}
|
@@ -79,11 +79,16 @@ public class Parser implements Listener {
|
|
79
79
|
listener.comment(content, line);
|
80
80
|
}
|
81
81
|
|
82
|
-
public void
|
83
|
-
if (event("
|
84
|
-
listener.
|
82
|
+
public void row(List<String> row, int line) {
|
83
|
+
if (event("row", line))
|
84
|
+
listener.row(row, line);
|
85
85
|
}
|
86
86
|
|
87
|
+
public void eof() {
|
88
|
+
if (event("eof", 1))
|
89
|
+
listener.eof();
|
90
|
+
}
|
91
|
+
|
87
92
|
public void syntax_error(String name, String event, List<String> strings, int line) {
|
88
93
|
}
|
89
94
|
|
@@ -154,6 +159,7 @@ public class Parser implements Listener {
|
|
154
159
|
}
|
155
160
|
}
|
156
161
|
Collections.sort(result);
|
162
|
+
result.remove("eof");
|
157
163
|
return result;
|
158
164
|
}
|
159
165
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
package gherkin.formatter;
|
2
|
+
|
3
|
+
import java.io.UnsupportedEncodingException;
|
4
|
+
import java.util.List;
|
5
|
+
|
6
|
+
public class Argument {
|
7
|
+
private final int byteOffset;
|
8
|
+
private final byte[] val;
|
9
|
+
|
10
|
+
public Argument(int byteOffset, String val) throws UnsupportedEncodingException {
|
11
|
+
this.byteOffset = byteOffset;
|
12
|
+
this.val = val.getBytes("UTF-8");
|
13
|
+
}
|
14
|
+
|
15
|
+
public static String format(String string, ArgumentFormat format, List<Argument> arguments) throws UnsupportedEncodingException {
|
16
|
+
return format(string, format, (Argument[]) arguments.toArray(new Argument[arguments.size()]));
|
17
|
+
}
|
18
|
+
|
19
|
+
public static String format(String string, ArgumentFormat format, Argument... arguments) throws UnsupportedEncodingException {
|
20
|
+
byte[] result = string.getBytes("UTF-8");
|
21
|
+
int offset = 0, pastOffset = 0;
|
22
|
+
for (Argument argument : arguments) {
|
23
|
+
if (argument.byteOffset != -1 && argument.byteOffset >= pastOffset) {
|
24
|
+
byte[] replacement = format.formatArgument(argument.val);
|
25
|
+
int delta = replacement.length - argument.val.length;
|
26
|
+
byte[] newResult = new byte[result.length + delta];
|
27
|
+
|
28
|
+
System.arraycopy(result, 0, newResult, 0, argument.byteOffset+offset);
|
29
|
+
System.arraycopy(replacement, 0, newResult, argument.byteOffset+offset, replacement.length);
|
30
|
+
int n = argument.byteOffset + argument.val.length + offset;
|
31
|
+
System.arraycopy(result, n, newResult, argument.byteOffset + replacement.length, result.length - n);
|
32
|
+
|
33
|
+
offset += delta;
|
34
|
+
result = newResult;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
return new String(result, "UTF-8");
|
38
|
+
}
|
39
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
package gherkin.formatter;
|
2
|
+
|
3
|
+
import java.io.UnsupportedEncodingException;
|
4
|
+
|
5
|
+
public class ArgumentFormat {
|
6
|
+
private final String prefix;
|
7
|
+
private final String suffix;
|
8
|
+
|
9
|
+
public ArgumentFormat(String prefix, String suffix) {
|
10
|
+
this.prefix = prefix;
|
11
|
+
this.suffix = suffix;
|
12
|
+
}
|
13
|
+
|
14
|
+
public byte[] formatArgument(byte[] argument) throws UnsupportedEncodingException {
|
15
|
+
return (prefix + new String(argument, "UTF-8") + suffix).getBytes("UTF-8");
|
16
|
+
}
|
17
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
package gherkin.formatter;
|
2
|
+
|
3
|
+
import gherkin.Listener;
|
4
|
+
|
5
|
+
import java.util.List;
|
6
|
+
|
7
|
+
/**
|
8
|
+
* This interface extends the Listener interface with extra methods for formatting
|
9
|
+
* Gherkin features during execution.
|
10
|
+
*/
|
11
|
+
public interface Formatter extends Listener {
|
12
|
+
void scenario(String keyword, String name, int line, String location);
|
13
|
+
void step(String keyword, String name, int line, String status, List<Argument> arguments, String location);
|
14
|
+
void flushTable();
|
15
|
+
}
|
@@ -0,0 +1,219 @@
|
|
1
|
+
package gherkin.formatter;
|
2
|
+
|
3
|
+
import java.io.OutputStream;
|
4
|
+
import java.io.PrintWriter;
|
5
|
+
import java.util.ArrayList;
|
6
|
+
import java.util.Collections;
|
7
|
+
import java.util.List;
|
8
|
+
import java.util.regex.Pattern;
|
9
|
+
|
10
|
+
import static gherkin.FixJava.join;
|
11
|
+
import static gherkin.formatter.Colors.*;
|
12
|
+
|
13
|
+
public class PrettyFormatter implements Formatter {
|
14
|
+
private final PrintWriter out;
|
15
|
+
private final boolean monochrome;
|
16
|
+
private int maxStepLength = 0;
|
17
|
+
private int[] stepLengths;
|
18
|
+
private int stepIndex;
|
19
|
+
private List<List<String>> rows;
|
20
|
+
private List<String> comments;
|
21
|
+
private List<String> tags;
|
22
|
+
|
23
|
+
public PrettyFormatter(OutputStream out, boolean monochrome) {
|
24
|
+
this.out = new PrintWriter(out);
|
25
|
+
this.monochrome = monochrome;
|
26
|
+
}
|
27
|
+
|
28
|
+
public void tag(String name, int line) {
|
29
|
+
if (tags == null) tags = new ArrayList<String>();
|
30
|
+
tags.add('@' + name);
|
31
|
+
}
|
32
|
+
|
33
|
+
public void comment(String content, int line) {
|
34
|
+
if (comments == null) comments = new ArrayList<String>();
|
35
|
+
comments.add(content);
|
36
|
+
}
|
37
|
+
|
38
|
+
public void feature(String keyword, String name, int line) {
|
39
|
+
printCommentsAndTags("");
|
40
|
+
out.println(keyword + ": " + indent(name, " "));
|
41
|
+
out.flush();
|
42
|
+
}
|
43
|
+
|
44
|
+
public void background(String keyword, String name, int line) {
|
45
|
+
out.println();
|
46
|
+
printCommentsAndTags(" ");
|
47
|
+
out.println(" " + keyword + ": " + name);
|
48
|
+
}
|
49
|
+
|
50
|
+
public void scenario(String keyword, String name, int line) {
|
51
|
+
scenario(keyword, name, line, null);
|
52
|
+
}
|
53
|
+
|
54
|
+
public void scenario(String keyword, String name, int line, String location) {
|
55
|
+
flushTable();
|
56
|
+
out.println();
|
57
|
+
printCommentsAndTags(" ");
|
58
|
+
out.println(" " + keyword + ": " + indent(name, " ") + indentedScenarioLocation(keyword, name, location));
|
59
|
+
out.flush();
|
60
|
+
}
|
61
|
+
|
62
|
+
public void scenario_outline(String keyword, String name, int line) {
|
63
|
+
flushTable();
|
64
|
+
out.println();
|
65
|
+
printCommentsAndTags(" ");
|
66
|
+
out.println(" " + keyword + ": " + name);
|
67
|
+
}
|
68
|
+
|
69
|
+
public void examples(String keyword, String name, int line) {
|
70
|
+
flushTable();
|
71
|
+
out.println();
|
72
|
+
printCommentsAndTags(" ");
|
73
|
+
out.println(" " + keyword + ": " + name);
|
74
|
+
}
|
75
|
+
|
76
|
+
public void step(String keyword, String name, int line, String status, List<Argument> arguments, String location) {
|
77
|
+
flushTable();
|
78
|
+
out.println(" " + keyword + indent(name, " ") + indentedStepLocation(location));
|
79
|
+
out.flush();
|
80
|
+
}
|
81
|
+
|
82
|
+
public void flushTable() {
|
83
|
+
if (rows == null) return;
|
84
|
+
int columnCount = rows.get(0).size();
|
85
|
+
int[][] cellLengths = new int[rows.size()][columnCount];
|
86
|
+
int[] maxLengths = new int[columnCount];
|
87
|
+
for (int i = 0; i < rows.size(); i++) {
|
88
|
+
for (int j = 0; j < columnCount; j++) {
|
89
|
+
int length = rows.get(i).get(j).length();
|
90
|
+
cellLengths[i][j] = length;
|
91
|
+
maxLengths[j] = Math.max(maxLengths[j], length);
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
for (int i = 0; i < rows.size(); i++) {
|
96
|
+
out.write(" | ");
|
97
|
+
for (int j = 0; j < columnCount; j++) {
|
98
|
+
out.write(rows.get(i).get(j));
|
99
|
+
padSpace(maxLengths[j] - cellLengths[i][j]);
|
100
|
+
if (j < columnCount - 1) {
|
101
|
+
out.write(" | ");
|
102
|
+
} else {
|
103
|
+
out.write(" |");
|
104
|
+
}
|
105
|
+
}
|
106
|
+
out.println();
|
107
|
+
}
|
108
|
+
out.flush();
|
109
|
+
rows = null;
|
110
|
+
}
|
111
|
+
|
112
|
+
public void step(String keyword, String name, int line) {
|
113
|
+
step(keyword, name, line, null, Collections.<Argument>emptyList(), null);
|
114
|
+
}
|
115
|
+
|
116
|
+
public void row(List<String> row, int line) {
|
117
|
+
if (rows == null) rows = new ArrayList<List<String>>();
|
118
|
+
rows.add(row);
|
119
|
+
}
|
120
|
+
|
121
|
+
public void py_string(String string, int line) {
|
122
|
+
out.println(" \"\"\"");
|
123
|
+
out.print(Pattern.compile("^", Pattern.MULTILINE).matcher(string).replaceAll(" "));
|
124
|
+
out.println("\n \"\"\"");
|
125
|
+
}
|
126
|
+
|
127
|
+
public void eof() {
|
128
|
+
flushTable();
|
129
|
+
out.flush();
|
130
|
+
}
|
131
|
+
|
132
|
+
public void syntax_error(String state, String event, List<String> legalEvents, int line) {
|
133
|
+
out.println("Syntax error:" + state + ' ' + event);
|
134
|
+
}
|
135
|
+
|
136
|
+
public void steps(List<List<String>> steps) {
|
137
|
+
stepLengths = new int[steps.size()];
|
138
|
+
int i = 0;
|
139
|
+
for (List<String> step : steps) {
|
140
|
+
int stepLength = step.get(0).length() + step.get(1).length();
|
141
|
+
stepLengths[i++] = stepLength;
|
142
|
+
maxStepLength = Math.max(maxStepLength, stepLength);
|
143
|
+
}
|
144
|
+
stepIndex = -1;
|
145
|
+
}
|
146
|
+
|
147
|
+
private void padSpace(int indent, StringBuffer buffer) {
|
148
|
+
for (int i = 0; i < indent; i++) {
|
149
|
+
buffer.append(" ");
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
private void padSpace(int indent) {
|
154
|
+
for (int i = 0; i < indent; i++) {
|
155
|
+
out.write(" ");
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
private void printCommentsAndTags(String indent) {
|
160
|
+
printComments(indent);
|
161
|
+
printTags(indent);
|
162
|
+
}
|
163
|
+
|
164
|
+
private boolean printComments(String indent) {
|
165
|
+
if (comments == null) return false;
|
166
|
+
for (String comment : comments) {
|
167
|
+
out.print(indent);
|
168
|
+
out.println(comment);
|
169
|
+
}
|
170
|
+
out.flush();
|
171
|
+
comments = null;
|
172
|
+
return true;
|
173
|
+
}
|
174
|
+
|
175
|
+
private boolean printTags(String indent) {
|
176
|
+
if (tags == null) return false;
|
177
|
+
out.print(indent);
|
178
|
+
out.println(join(tags, " "));
|
179
|
+
out.flush();
|
180
|
+
tags = null;
|
181
|
+
return true;
|
182
|
+
}
|
183
|
+
|
184
|
+
private String indent(String name, String indentation) {
|
185
|
+
String indent = "";
|
186
|
+
StringBuilder sb = new StringBuilder();
|
187
|
+
String[] lines = name.split("\\n");
|
188
|
+
for (int i = 0; i < lines.length; i++) {
|
189
|
+
sb.append(indent).append(lines[i]);
|
190
|
+
if (i < lines.length - 1) {
|
191
|
+
sb.append("\n");
|
192
|
+
}
|
193
|
+
indent = indentation;
|
194
|
+
}
|
195
|
+
return sb.toString();
|
196
|
+
}
|
197
|
+
|
198
|
+
private String indentedScenarioLocation(String keyword, String name, String location) {
|
199
|
+
if (location == null || "".equals(location)) return "";
|
200
|
+
int l = keyword.length() + name.length();
|
201
|
+
maxStepLength = Math.max(maxStepLength, l);
|
202
|
+
int indent = maxStepLength - l;
|
203
|
+
|
204
|
+
StringBuffer buffer = new StringBuffer();
|
205
|
+
padSpace(indent, buffer);
|
206
|
+
buffer.append(" ").append(comments("# " + location, monochrome));
|
207
|
+
return buffer.toString();
|
208
|
+
}
|
209
|
+
|
210
|
+
private String indentedStepLocation(String location) {
|
211
|
+
if (location == null || "".equals(location)) return "";
|
212
|
+
int indent = maxStepLength - stepLengths[stepIndex += 1];
|
213
|
+
|
214
|
+
StringBuffer buffer = new StringBuffer();
|
215
|
+
padSpace(indent, buffer);
|
216
|
+
buffer.append(" ").append(comments("# " + location, monochrome));
|
217
|
+
return buffer.toString();
|
218
|
+
}
|
219
|
+
}
|
@@ -7,6 +7,7 @@ import gherkin.lexer.En;
|
|
7
7
|
|
8
8
|
import java.io.IOException;
|
9
9
|
import java.util.List;
|
10
|
+
import java.util.ArrayList;
|
10
11
|
|
11
12
|
public class StateMachineReader implements Listener {
|
12
13
|
private final String machinePath;
|
@@ -17,9 +18,10 @@ public class StateMachineReader implements Listener {
|
|
17
18
|
}
|
18
19
|
|
19
20
|
public List<List<String>> transitionTable() {
|
21
|
+
transitionTable = new ArrayList<List<String>>();
|
20
22
|
Lexer lexer = new En(this);
|
21
23
|
try {
|
22
|
-
lexer.scan(FixJava.
|
24
|
+
lexer.scan(FixJava.readResource(machinePath));
|
23
25
|
} catch (IOException e) {
|
24
26
|
throw new RuntimeException("Fatal error. Couldn't read " + machinePath);
|
25
27
|
}
|
@@ -53,10 +55,13 @@ public class StateMachineReader implements Listener {
|
|
53
55
|
public void py_string(String string, int line) {
|
54
56
|
}
|
55
57
|
|
58
|
+
public void eof() {
|
59
|
+
}
|
60
|
+
|
56
61
|
public void syntax_error(String name, String event, List<String> strings, int line) {
|
57
62
|
}
|
58
63
|
|
59
|
-
public void
|
60
|
-
transitionTable
|
64
|
+
public void row(List<String> row, int line) {
|
65
|
+
transitionTable.add(row);
|
61
66
|
}
|
62
67
|
}
|