我已经开始掌握Xtext的使用方法,但我在用多个换行符分隔语义部分时还是遇到了一些问题。
grammar org.example.dsl.MyDsl hidden(WS)
import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate words "http://www.example.org/dsl
Document:
sections+=Paragraph+
;
Paragraph:
lines+=Text+
( -> NL)
;
Text:
value=WordGroup
NL
;
WordGroup: SIMPLE_WORD+;
terminal SIMPLE_WORD:
('0'..'9' | 'a'..'z' | 'A'..'Z')
('0'..'9' | 'a'..'z' | 'A'..'Z' | '-' | '_' | '.')*
;
terminal NL: ('\r'? '\n');
terminal WS: (' ' | '\t');
这个可以...
@Test
def void happyPath() {
val model = parseHelper.parse('''
The quick brown fox
Jumps over the lazy dog
''')
assertThat(model, notNullValue())
assertThat(model.eResource.errors, equalTo(#[]))
assertThat(model.sections.size(), equalTo(1))
assertThat(model.sections.get(0).lines.size(), equalTo(2))
// It works!
}
但这个不行...
@Test
def void noTrailingNewlines() {
val model = parseHelper.parse('''
The quick brown fox
Jumps over the lazy dog
''')
assertThat(model, notNullValue())
assertThat(model.eResource.errors, equalTo(#[]))
// Fail ^^^ XtextSyntaxDiagnostic: null:2 mismatched input '<EOF>' expecting RULE_NL
assertThat(model.sections.size(), equalTo(1))
assertThat(model.sections.get(0).lines.size(), equalTo(2))
}
两者都应该是有效的可解析文本,但我不能让它接受一个单一的 NL,如果那是找到的最后一个字符。
我尝试了明显的 ( -> NL?)
...
Paragraph:
lines+=Text+
( -> NL?)
;
...而这实际上确实导致测试通过,只是现在我有ANTLR警告。
正如我所怀疑的那样,这只是把问题踢到了路上......
@Test
def void multipleParagraphs() {
val model = parseHelper.parse('''
The quick brown fox
Jumps over the lazy dog
But only on days that end in Y
''')
assertThat(model, notNullValue())
assertThat(model.eResource.errors, equalTo(#[]))
assertThat(model.sections.size(), equalTo(2)) //Expected: <2> but: was <1>
}
我们有一个赢家
非常感谢@christian-dietrich和@redknite,他们对我非常有耐心,帮助我解决了这个问题。
Document:
sections+=Paragraph
(NL sections+=Paragraph)*
;
Paragraph:
lines+=Text+
;
Text:
value=WordGroup
NL
;
@Test
def void singleParagraph() {
val model = parseHelper.parse('''
The quick brown fox
Jumps over the lazy dog
''')
assertThat(model, notNullValue())
assertThat(model.eResource.errors, equalTo(#[]))
val doc = model.document
assertThat(doc, notNullValue())
assertThat(doc.sections.size(), equalTo(1))
assertThat(doc.sections.get(0).lines.size(), equalTo(2))
}
@Test
def void multiParagraph() {
val model = parseHelper.parse('''
The quick brown fox
Jumps over the lazy dog
But only on days that end in Y
''')
assertThat(model, notNullValue())
assertThat(model.eResource.errors, equalTo(#[]))
val doc = model.document
assertThat(doc, notNullValue())
assertThat(doc.sections.size(), equalTo(2))
assertThat(doc.sections.get(0).lines.size(), equalTo(2))
}
两人都通过了!