Я только начинаю работать с Xtext, и у меня возникли некоторые проблемы с использованием семантического семантического ряда (новые строки влияют на то, как лексер назначает фрагменты).
Вот очень простой тестовый пример:
Feature: The quick brown fox
Jumps over
The lazy dog
При разборе этого текста с использованием этой грамматики ...
grammar com.example.model.Model hidden(WS)
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate model "http://www.example.com/model"
Feature:
'Feature' ':' title=Title NL+
narrative=Narrative?;
Title:
(WORD) (WORD)*;
Narrative:
((WORD) (WORD)* NL+)+;
terminal WORD: ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z')*;
// WS should not include newlines because it is semantic
terminal WS: (' ' | '\t');
terminal NL: ('\r'? '\n');
Я ожидаю, что заголовок будет содержать "Быстрая коричневая лиса", а повествование будет содержать "Прыжки через \ nЛенивая собака"
Но вместо этого я получаю org.eclipse.xtext.diagnostics.Diagnostic.Syntax
ошибку extraneous input '\n' expecting 'Feature'
.
Однако, если я удалю описательную часть из текста примера, я не получу ошибок разбора с правильно назначенным заголовком.
Я просмотрел множество примеров, но они, как правило, предназначены для очень больших и сложных языков или имеют очень четкие начальные / конечные теги для сопоставления.
Может кто-нибудь помочь объяснить, где мои ожидания не удалось в этом очень простом случае?
Обновление
Так что, очевидно, мои ожидания были правильными, это мой тестовый случай, который терпит неудачу.
@RunWith(XtextRunner)
@InjectWith(CucumberInjectorProvider)
class ValidationTest {
static void assertThatValidation(List<Issue> issues, Matcher matches) {
assertThat(issues, matches)
}
static Matcher hasNoIssues() {
return emptyCollectionOf(Issue)
}
static Matcher theError(String expectedCode) {
return allOf(hasProperty("code", equalTo(expectedCode)),
hasProperty("severity", equalTo(Severity.ERROR)))
}
static Matcher theWarning(String expectedCode) {
return allOf(hasProperty("code", equalTo(expectedCode)),
hasProperty("severity", equalTo(Severity.WARNING)))
}
@Inject
ParseHelper<Feature> parserHelper
@Inject
ValidationTestHelper validationTestHelper
List<Issue> whenParsing(String content) {
Feature model = parserHelper.parse(content.stripIndent())
assertThat(model, not(null))
return validationTestHelper.validate(model)
}
@Test
void featureWithSimpleTitle() {
assertThatValidation whenParsing("Feature: Hello World\n"),
hasNoIssues()
}
@Test
void featureWithSimpleTitleAndNarrative() {
def input = '''
Feature: The quick brown fox
Jumps over
The lazy dog
'''
assertThatValidation whenParsing(input), hasNoIssues()
}
}
Но это кажется нормальным ...
@RunWith(XtextRunner)
@InjectWith(CucumberInjectorProvider)
class CucumberParsingTest {
@Inject
ParseHelper<Feature> parseHelper
@Test
def void loadModel() {
val result = parseHelper.parse('''
Feature: The quick brown fox
Jumps over
The lazy dog
''')
Assert.assertNotNull(result)
val errors = result.eResource.errors
Assert.assertTrue('''Unexpected errors: «errors.join(", ")»''', errors.isEmpty)
}
}
Извините, мои вопросы закончились так, что я не в курсе ... 1032 *.