Проблемы с созданием грамматики Xtext с помощью semanti c newlines - PullRequest
1 голос
/ 27 апреля 2020

Я только начинаю работать с 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 *.

...