gherkin 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/.gitattributes +1 -0
  2. data/History.txt +18 -0
  3. data/README.rdoc +4 -1
  4. data/Rakefile +4 -2
  5. data/VERSION.yml +1 -1
  6. data/bin/gherkin +1 -1
  7. data/dotnet/.gitignore +13 -0
  8. data/features/feature_parser.feature +22 -2
  9. data/features/native_lexer.feature +1 -1
  10. data/features/parser_with_native_lexer.feature +1 -1
  11. data/features/step_definitions/gherkin_steps.rb +2 -6
  12. data/features/step_definitions/pretty_printer_steps.rb +2 -3
  13. data/features/steps_parser.feature +1 -1
  14. data/gherkin.gemspec +53 -24
  15. data/java/Gherkin.iml +2 -4
  16. data/java/build.xml +3 -0
  17. data/java/src/gherkin/FixJava.java +6 -3
  18. data/java/src/gherkin/I18nLexer.java +48 -0
  19. data/java/src/gherkin/Listener.java +3 -1
  20. data/java/src/gherkin/Main.java +17 -0
  21. data/java/src/gherkin/Parser.java +9 -3
  22. data/java/src/gherkin/formatter/Argument.java +39 -0
  23. data/java/src/gherkin/formatter/ArgumentFormat.java +17 -0
  24. data/java/src/gherkin/formatter/Colors.java +7 -0
  25. data/java/src/gherkin/formatter/Formatter.java +15 -0
  26. data/java/src/gherkin/formatter/PrettyFormatter.java +219 -0
  27. data/java/src/gherkin/parser/StateMachineReader.java +8 -3
  28. data/java/test/gherkin/formatter/ArgumentTest.java +17 -0
  29. data/lib/gherkin/csharp_lexer.rb +15 -0
  30. data/lib/gherkin/format/argument.rb +35 -0
  31. data/lib/gherkin/format/monochrome_format.rb +9 -0
  32. data/lib/gherkin/i18n.rb +22 -0
  33. data/lib/gherkin/i18n.yml +34 -20
  34. data/lib/gherkin/i18n_lexer.rb +57 -13
  35. data/lib/gherkin/lexer.rb +9 -18
  36. data/lib/gherkin/parser.rb +3 -3
  37. data/lib/gherkin/parser/meta.txt +5 -4
  38. data/lib/gherkin/parser/root.txt +11 -9
  39. data/lib/gherkin/parser/steps.txt +4 -3
  40. data/lib/gherkin/rb_parser.rb +13 -5
  41. data/lib/gherkin/tools/colors.rb +119 -0
  42. data/lib/gherkin/tools/files.rb +6 -1
  43. data/lib/gherkin/tools/pretty_listener.rb +115 -23
  44. data/ragel/lexer.c.rl.erb +67 -51
  45. data/ragel/lexer.csharp.rl.erb +240 -0
  46. data/ragel/lexer.java.rl.erb +27 -18
  47. data/ragel/lexer.rb.rl.erb +17 -17
  48. data/ragel/lexer_common.rl.erb +8 -8
  49. data/spec/gherkin/c_lexer_spec.rb +4 -4
  50. data/spec/gherkin/csharp_lexer_spec.rb +20 -0
  51. data/spec/gherkin/fixtures/comments_in_table.feature +9 -0
  52. data/spec/gherkin/fixtures/complex.feature +2 -0
  53. data/spec/gherkin/fixtures/dos_line_endings.feature +45 -0
  54. data/spec/gherkin/fixtures/i18n_fr.feature +1 -0
  55. data/spec/gherkin/fixtures/i18n_no.feature +1 -0
  56. data/spec/gherkin/fixtures/i18n_zh-CN.feature +1 -0
  57. data/spec/gherkin/format/argument_spec.rb +28 -0
  58. data/spec/gherkin/i18n_lexer_spec.rb +4 -4
  59. data/spec/gherkin/i18n_spec.rb +31 -23
  60. data/spec/gherkin/java_lexer_spec.rb +4 -3
  61. data/spec/gherkin/parser_spec.rb +5 -0
  62. data/spec/gherkin/rb_lexer_spec.rb +4 -2
  63. data/spec/gherkin/sexp_recorder.rb +1 -1
  64. data/spec/gherkin/shared/lexer_spec.rb +169 -60
  65. data/spec/gherkin/shared/py_string_spec.rb +6 -0
  66. data/spec/gherkin/shared/row_spec.rb +107 -0
  67. data/spec/gherkin/shared/tags_spec.rb +1 -1
  68. data/spec/gherkin/tools/colors_spec.rb +19 -0
  69. data/spec/gherkin/tools/pretty_listener_spec.rb +147 -0
  70. data/spec/spec_helper.rb +31 -7
  71. data/tasks/compile.rake +81 -7
  72. data/tasks/ragel_task.rb +6 -4
  73. data/tasks/rspec.rake +2 -2
  74. metadata +104 -41
  75. data/lib/gherkin/java_lexer.rb +0 -10
  76. data/spec/gherkin/shared/table_spec.rb +0 -97
@@ -0,0 +1,240 @@
1
+ namespace Gherkin.Lexer
2
+ {
3
+ using System.Text;
4
+ using System.Text.RegularExpressions;
5
+ using System.IO;
6
+ using System.Collections.Generic;
7
+ using System.Linq;
8
+
9
+ [Language("<%= @i18n.sanitized_key.downcase %>")]
10
+ public class <%= @i18n.sanitized_key.capitalize %> : ILexer {
11
+ %%{
12
+ machine lexer;
13
+ alphtype char;
14
+
15
+ action begin_content {
16
+ contentStart = p;
17
+ contentCol = p - lastNewline + 1;
18
+ contentNewline = lastNewline;
19
+ currentLine = lineNumber;
20
+ }
21
+
22
+ action start_pystring {
23
+ currentLine = lineNumber;
24
+ pystringStartCol = p - lastNewline;
25
+ pystringStartNewline = lastNewline;
26
+ }
27
+
28
+ action begin_pystring_content {
29
+ contentStart = p;
30
+ }
31
+
32
+ action store_pystring_content {
33
+ string con = Unindent(pystringStartCol, new Regex("(\\r?\\n)?( )*\\Z").Replace(Substring(data, contentStart, nextKeywordStart-1), "", 1));
34
+ listener.PythonString(new Token(con, GetCharacterPosition(data, pystringStartNewline, currentLine, pystringStartCol+1)));
35
+ }
36
+
37
+ action store_feature_content {
38
+ string con = MultilineStrip(KeywordContent(data, p, eof, nextKeywordStart, contentStart).Trim());
39
+ listener.Feature(new Token(keyword, GetCharacterPosition(data, keywordNewline, currentLine, keywordCol)), new Token(con, GetCharacterPosition(data, contentNewline, currentLine, contentCol)));
40
+ if(nextKeywordStart != -1) p = nextKeywordStart - 1;
41
+ nextKeywordStart = -1;
42
+ }
43
+
44
+ action store_background_content {
45
+ string con = MultilineStrip(KeywordContent(data, p, eof, nextKeywordStart, contentStart));
46
+ listener.Background(new Token(keyword, GetCharacterPosition(data, keywordNewline, currentLine, keywordCol)), new Token(con, GetCharacterPosition(data, contentNewline, currentLine, contentCol)));
47
+ if(nextKeywordStart != -1) p = nextKeywordStart - 1;
48
+ nextKeywordStart = -1;
49
+ }
50
+
51
+ action store_scenario_content {
52
+ string con = MultilineStrip(KeywordContent(data, p, eof, nextKeywordStart, contentStart));
53
+ listener.Scenario(new Token(keyword, GetCharacterPosition(data, keywordNewline, currentLine, keywordCol)), new Token(con, GetCharacterPosition(data, contentNewline, currentLine, contentCol)));
54
+ if(nextKeywordStart != -1) p = nextKeywordStart - 1;
55
+ nextKeywordStart = -1;
56
+ }
57
+
58
+ action store_scenario_outline_content {
59
+ string con = MultilineStrip(KeywordContent(data, p, eof, nextKeywordStart, contentStart));
60
+ listener.ScenarioOutline(new Token(keyword, GetCharacterPosition(data, keywordNewline, currentLine, keywordCol)), new Token(con, GetCharacterPosition(data, contentNewline, currentLine, contentCol)));
61
+ if(nextKeywordStart != -1) p = nextKeywordStart - 1;
62
+ nextKeywordStart = -1;
63
+ }
64
+
65
+ action store_examples_content {
66
+ string con = MultilineStrip(KeywordContent(data, p, eof, nextKeywordStart, contentStart));
67
+ listener.Examples(new Token(keyword, GetCharacterPosition(data, keywordNewline, currentLine, keywordCol)), new Token(con, GetCharacterPosition(data, contentNewline, currentLine, contentCol)));
68
+ if(nextKeywordStart != -1) p = nextKeywordStart - 1;
69
+ nextKeywordStart = -1;
70
+ }
71
+
72
+ action store_step_content {
73
+ listener.Step(
74
+ new Token(keyword, GetCharacterPosition(data, keywordNewline, currentLine, keywordCol)),
75
+ new Token(Substring(data, contentStart, p).Trim(), GetCharacterPosition(data, contentNewline, currentLine, contentCol)),
76
+ LookupStepKind(keyword));
77
+ }
78
+
79
+ action store_comment_content {
80
+ listener.Comment(new Token(Substring(data, contentStart, p).Trim(), GetCharacterPosition(data, contentNewline, currentLine, contentCol)));
81
+ keywordStart = -1;
82
+ }
83
+
84
+ action store_tag_content {
85
+ listener.Tag(new Token(Substring(data, contentStart, p).Trim(), GetCharacterPosition(data, contentNewline, currentLine, contentCol-1)));
86
+ keywordStart = -1;
87
+ }
88
+
89
+ action inc_line_number {
90
+ lineNumber++;
91
+ }
92
+
93
+ action last_newline {
94
+ lastNewline = p + 1;
95
+ }
96
+
97
+ action start_keyword {
98
+ if(keywordStart == -1) keywordStart = p;
99
+ if(nextKeywordStart == -1)
100
+ {
101
+ keywordCol = p - lastNewline + 1;
102
+ keywordNewline = lastNewline;
103
+ }
104
+ }
105
+
106
+ action end_keyword {
107
+ keyword = new Regex(":$").Replace(Substring(data, keywordStart, p), "", 1);
108
+ keywordStart = -1;
109
+ }
110
+
111
+ action next_keyword_start {
112
+ nextKeywordStart = p;
113
+ }
114
+
115
+ action start_row {
116
+ p = p - 1;
117
+ contentCol = p - lastNewline + 1;
118
+ currentRow = new List<Token>();
119
+ currentLine = lineNumber;
120
+ }
121
+
122
+ action begin_cell_content {
123
+ contentStart = p;
124
+ }
125
+
126
+ action store_cell_content {
127
+ currentRow.Add(new Token(Substring(data, contentStart, p).Trim(), GetCharacterPosition(data, lastNewline, lineNumber, contentStart - lastNewline + 1)));
128
+ }
129
+
130
+ action store_row {
131
+ listener.Row(currentRow, GetCharacterPosition(data, contentNewline, currentLine, contentCol));
132
+ }
133
+
134
+ action end_feature {
135
+ if(cs < lexer_first_final) {
136
+ string content = CurrentLineContent(data, lastNewline);
137
+ throw new LexingException("Lexing error on line " + lineNumber + ": '" + content + "'");
138
+ } else {
139
+ listener.Eof();
140
+ }
141
+ }
142
+
143
+ include lexer_common "lexer_common.<%= @i18n.sanitized_key %>.rl";
144
+ }%%
145
+
146
+ private readonly IListener listener;
147
+
148
+ private static readonly IDictionary<string, StepKind> stepKeywords = new Dictionary<string, StepKind>();
149
+
150
+ static <%= @i18n.sanitized_key.capitalize %>()
151
+ {
152
+ <% @i18n.keywords('given', true).reject{|kw| kw == '* '}.each do |keyword| %>
153
+ stepKeywords["<%=keyword%>"] = StepKind.Given;
154
+ <% end %>
155
+ <% @i18n.keywords('when', true).reject{|kw| kw == '* '}.each do |keyword| %>
156
+ stepKeywords["<%=keyword%>"] = StepKind.When;
157
+ <% end %>
158
+ <% @i18n.keywords('then', true).reject{|kw| kw == '* '}.each do |keyword| %>
159
+ stepKeywords["<%=keyword%>"] = StepKind.Then;
160
+ <% end %>
161
+ <% @i18n.keywords('and', true).reject{|kw| kw == '* '}.each do |keyword| %>
162
+ stepKeywords["<%=keyword%>"] = StepKind.And;
163
+ <% end %>
164
+ <% @i18n.keywords('but', true).reject{|kw| kw == '* '}.each do |keyword| %>
165
+ stepKeywords["<%=keyword%>"] = StepKind.But;
166
+ <% end %>
167
+ stepKeywords["* "] = StepKind.Any;
168
+ }
169
+
170
+ private static StepKind LookupStepKind(string keyword)
171
+ {
172
+ if (!stepKeywords.Keys.Contains(keyword))
173
+ return StepKind.Unknown;
174
+ return stepKeywords[keyword];
175
+ }
176
+
177
+ public <%= @i18n.sanitized_key.capitalize %>(IListener listener) {
178
+ this.listener = listener;
179
+
180
+ }
181
+
182
+ %% write data noerror;
183
+
184
+ public void Scan(TextReader inputSequence) {
185
+ string input = inputSequence.ReadToEnd() + "\n%_FEATURE_END_%";
186
+ char[] data = Encoding.GetEncoding("iso-8859-1").GetChars(Encoding.UTF8.GetBytes(input));
187
+ int cs, p = 0, pe = data.Length;
188
+ int eof = pe;
189
+
190
+ int lineNumber = 1;
191
+ int lastNewline = 0;
192
+
193
+ int keywordCol = -1;
194
+ int keywordNewline = 0;
195
+ int contentCol = -1;
196
+ int contentNewline = 0;
197
+ int contentStart = -1;
198
+ int currentLine = -1;
199
+ int pystringStartNewline = 0;
200
+ int pystringStartCol = -1;
201
+ int nextKeywordStart = -1;
202
+ int keywordStart = -1;
203
+ string keyword = null;
204
+ IList<Token> currentRow = null;
205
+
206
+ %% write init;
207
+ %% write exec;
208
+ }
209
+
210
+ private string KeywordContent(char[] data, int p, int eof, int nextKeywordStart, int contentStart) {
211
+ int endPoint = (nextKeywordStart == -1 || (p == eof)) ? p : nextKeywordStart;
212
+ return Substring(data, contentStart, endPoint);
213
+ }
214
+
215
+ private string MultilineStrip(string text) {
216
+ var result = new StringBuilder();
217
+ foreach (var s in text.Split(new [] {'\n'})) {
218
+ result.AppendLine(s.Trim());
219
+ }
220
+ return result.ToString().Trim();
221
+ }
222
+
223
+ private string Unindent(int startCol, string text) {
224
+ return new Regex("^ {0," + startCol + "}", RegexOptions.Multiline).Replace(text, "");
225
+ }
226
+
227
+ private string CurrentLineContent(char[] data, int lastNewline) {
228
+ return Substring(data, lastNewline, data.Length).Trim();
229
+ }
230
+
231
+ private string Substring(char[] data, int start, int end) {
232
+ return Encoding.UTF8.GetString(Encoding.GetEncoding("iso-8859-1").GetBytes(data, start, end-start));
233
+ }
234
+
235
+ private Position GetCharacterPosition(char[] data, int lineStart, int line, int bytecol) {
236
+ return new Position(line,
237
+ Encoding.UTF8.GetCharCount(Encoding.GetEncoding("iso-8859-1").GetBytes(data, lineStart, bytecol)));
238
+ }
239
+ }
240
+ }
@@ -3,6 +3,7 @@ package gherkin.lexer;
3
3
  import java.util.List;
4
4
  import java.util.ArrayList;
5
5
  import java.util.regex.Pattern;
6
+ import java.util.regex.Matcher;
6
7
  import gherkin.Lexer;
7
8
  import gherkin.Listener;
8
9
  import gherkin.LexingError;
@@ -93,7 +94,7 @@ public class <%= @i18n.sanitized_key.capitalize %> implements Lexer {
93
94
  }
94
95
 
95
96
  action end_keyword {
96
- keyword = substring(data, keywordStart, p).replaceFirst(":$","").trim();
97
+ keyword = substring(data, keywordStart, p).replaceFirst(":$","");
97
98
  keywordStart = -1;
98
99
  }
99
100
 
@@ -101,14 +102,10 @@ public class <%= @i18n.sanitized_key.capitalize %> implements Lexer {
101
102
  nextKeywordStart = p;
102
103
  }
103
104
 
104
- action start_table {
105
- p = p - 1;
106
- rows = new ArrayList<List<String>>();
107
- currentLine = lineNumber;
108
- }
109
-
110
105
  action start_row {
106
+ p = p - 1;
111
107
  currentRow = new ArrayList<String>();
108
+ currentLine = lineNumber;
112
109
  }
113
110
 
114
111
  action begin_cell_content {
@@ -120,19 +117,15 @@ public class <%= @i18n.sanitized_key.capitalize %> implements Lexer {
120
117
  }
121
118
 
122
119
  action store_row {
123
- rows.add(currentRow);
124
- }
125
-
126
- action store_table {
127
- if(!rows.isEmpty()) {
128
- listener.table(rows, currentLine);
129
- }
120
+ listener.row(currentRow, currentLine);
130
121
  }
131
122
 
132
123
  action end_feature {
133
124
  if(cs < lexer_first_final) {
134
125
  String content = currentLineContent(data, lastNewline);
135
- throw new LexingError("Lexing error on line " + lineNumber);
126
+ throw new LexingError("Lexing error on line " + lineNumber + ": '" + content + "'");
127
+ } else {
128
+ listener.eof();
136
129
  }
137
130
  }
138
131
 
@@ -162,7 +155,6 @@ public class <%= @i18n.sanitized_key.capitalize %> implements Lexer {
162
155
  int nextKeywordStart = -1;
163
156
  int keywordStart = -1;
164
157
  String keyword = null;
165
- List<List<String>> rows = null;
166
158
  List<String> currentRow = null;
167
159
 
168
160
  %% write init;
@@ -174,14 +166,31 @@ public class <%= @i18n.sanitized_key.capitalize %> implements Lexer {
174
166
  return substring(data, contentStart, endPoint);
175
167
  }
176
168
 
169
+ private static final Pattern CRLF_RE = Pattern.compile("\r\n");
170
+ private static final Pattern LF_RE = Pattern.compile("[^\r]\n");
171
+ private static final String CRLF = "\r\n";
172
+ private static final String LF = "\n";
173
+
177
174
  private String multilineStrip(String text) {
175
+ int crlfCount = matchCount(CRLF_RE.matcher(text));
176
+ int lfCount = matchCount(LF_RE.matcher(text));
177
+ String eol = crlfCount > lfCount ? CRLF : LF;
178
+
178
179
  StringBuffer result = new StringBuffer();
179
- for(String s : text.split("\n")) {
180
- result.append(s.trim()).append("\n");
180
+ for(String s : text.split("\r?\n")) {
181
+ result.append(s.trim()).append(eol);
181
182
  }
182
183
  return result.toString().trim();
183
184
  }
184
185
 
186
+ private int matchCount(Matcher m) {
187
+ int count = 0;
188
+ while(m.find()) {
189
+ count++;
190
+ }
191
+ return count;
192
+ }
193
+
185
194
  private String unindent(int startCol, String text) {
186
195
  return Pattern.compile("^ {0," + startCol + "}", Pattern.MULTILINE).matcher(text).replaceAll("");
187
196
  }
@@ -85,7 +85,7 @@ module Gherkin
85
85
  }
86
86
 
87
87
  action end_keyword {
88
- @keyword = data[@keyword_start...p].utf8_pack("c*").sub(/:$/,'').strip
88
+ @keyword = data[@keyword_start...p].utf8_pack("c*").sub(/:$/,'')
89
89
  @keyword_start = nil
90
90
  }
91
91
 
@@ -93,16 +93,12 @@ module Gherkin
93
93
  @next_keyword_start = p
94
94
  }
95
95
 
96
- action start_table {
96
+ action start_row {
97
97
  p = p - 1
98
- @rows = []
98
+ current_row = []
99
99
  @current_line = @line_number
100
100
  }
101
101
 
102
- action start_row {
103
- current_row = []
104
- }
105
-
106
102
  action begin_cell_content {
107
103
  @content_start = p
108
104
  }
@@ -113,19 +109,15 @@ module Gherkin
113
109
  }
114
110
 
115
111
  action store_row {
116
- @rows << current_row
112
+ @listener.row(current_row, @current_line)
117
113
  }
118
114
 
119
- action store_table {
120
- if @rows.size != 0
121
- @listener.table(@rows, @current_line)
122
- end
123
- }
124
-
125
115
  action end_feature {
126
116
  if cs < lexer_first_final
127
117
  content = current_line_content(data, p)
128
- raise Lexer::LexingError.new("Lexing error on line %d: '%s'." % [@line_number, content])
118
+ raise LexingError.new("Lexing error on line %d: '%s'." % [@line_number, content])
119
+ else
120
+ @listener.eof
129
121
  end
130
122
  }
131
123
 
@@ -147,9 +139,17 @@ module Gherkin
147
139
  %% write init;
148
140
  %% write exec;
149
141
  end
150
-
142
+
143
+ CRLF_RE = /\r\n/
144
+ LF_RE = /[^\r]\n/
145
+ CRLF = "\r\n"
146
+ LF = "\n"
147
+
151
148
  def multiline_strip(text)
152
- text.split("\n").map{|s| s.strip}.join("\n").strip
149
+ crlf_count = text.scan(CRLF_RE).size
150
+ lf_count = text.scan(LF_RE).size
151
+ eol = crlf_count > lf_count ? CRLF : LF
152
+ text.split(/\r?\n/).map{|s| s.strip}.join(eol).strip
153
153
  end
154
154
 
155
155
  def unindent(startcol, text)
@@ -10,7 +10,7 @@
10
10
  I18N_Examples = (<%= ragel_list(@i18n.examples_keywords) %> ':') >start_keyword %end_keyword;
11
11
 
12
12
  EOF = '%_FEATURE_END_%'; # Explicit EOF added before scanning begins
13
- EOL = ('\r'? '\n') @inc_line_number @last_newline;
13
+ EOL = ('\n' | '\r\n') @inc_line_number @last_newline;
14
14
 
15
15
  FeatureHeadingEnd = EOL+ space* (I18N_Background | I18N_Scenario | I18N_ScenarioOutline | '@' | '#' | EOF) >next_keyword_start;
16
16
  ScenarioHeadingEnd = EOL+ space* ( I18N_Scenario | I18N_ScenarioOutline | I18N_Step | '@' | '#' | EOF ) >next_keyword_start;
@@ -24,23 +24,23 @@
24
24
  ScenarioOutlineHeading = space* I18N_ScenarioOutline %begin_content ^ScenarioOutlineHeadingEnd* :>> ScenarioOutlineHeadingEnd @store_scenario_outline_content;
25
25
  ExamplesHeading = space* I18N_Examples %begin_content ^ExamplesHeadingEnd* :>> ExamplesHeadingEnd @store_examples_content;
26
26
 
27
- Step = space* I18N_Step %begin_content ^EOL+ %store_step_content EOL+;
28
- Comment = space* '#' >begin_content ^EOL* %store_comment_content EOL+;
27
+ Step = space* I18N_Step %begin_content ^EOL+ %store_step_content :> EOL+;
28
+ Comment = space* '#' >begin_content ^EOL* %store_comment_content :> EOL+;
29
29
 
30
30
  Tag = ( '@' [^@\r\n\t ]+ >begin_content ) %store_tag_content;
31
31
  Tags = space* (Tag space*)+ EOL+;
32
32
 
33
- StartTable = space* '|' >start_table;
34
- EndTable = EOL space* ^('|') >next_keyword_start;
33
+ StartRow = space* '|' >start_row;
34
+ EndRow = EOL space* ^('|') >next_keyword_start;
35
35
  Cell = '|' (any - '|')* >begin_cell_content %store_cell_content;
36
- Row = space* Cell* >start_row '|' :>> (space* EOL+ space*) %store_row;
37
- Table = StartTable :>> Row+ %store_table <: EndTable?;
36
+ RowBody = space* Cell* '|' :>> (space* EOL+ space*) %store_row;
37
+ Row = StartRow :>> RowBody <: EndRow?;
38
38
 
39
39
  StartPyString = '"""' >start_pystring space* :>> EOL;
40
40
  EndPyString = (space* '"""') >next_keyword_start;
41
41
  PyString = space* StartPyString %begin_pystring_content (^EOL | EOL)* :>> EndPyString %store_pystring_content space* EOL+;
42
42
 
43
- Tokens = (space | EOL)* (Tags | Comment | FeatureHeading | BackgroundHeading | ScenarioHeading | ScenarioOutlineHeading | ExamplesHeading | Step | Table | PyString)* (space | EOL)* EOF;
43
+ Tokens = (space | EOL)* (Tags | Comment | FeatureHeading | BackgroundHeading | ScenarioHeading | ScenarioOutlineHeading | ExamplesHeading | Step | Row | PyString)* (space | EOL)* EOF;
44
44
 
45
45
  main := Tokens %end_feature @!end_feature;
46
46
  }%%
@@ -1,21 +1,21 @@
1
1
  #encoding: utf-8
2
2
  unless defined?(JRUBY_VERSION)
3
3
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
4
- require 'gherkin/c_lexer'
4
+ require 'gherkin_lexer_en'
5
5
 
6
6
  module Gherkin
7
7
  module Lexer
8
8
  describe "C Lexer" do
9
9
  before do
10
10
  @listener = Gherkin::SexpRecorder.new
11
- @lexer = Gherkin::CLexer['en'].new(@listener)
11
+ @lexer = Gherkin::CLexer::En.new(@listener)
12
12
  end
13
13
 
14
14
  it_should_behave_like "a Gherkin lexer"
15
15
  it_should_behave_like "a Gherkin lexer lexing tags"
16
16
  it_should_behave_like "a Gherkin lexer lexing py_strings"
17
- it_should_behave_like "a Gherkin lexer lexing tables"
17
+ it_should_behave_like "a Gherkin lexer lexing rows"
18
18
  end
19
19
  end
20
20
  end
21
- end
21
+ end