Xtext/ANTLR 中的多行文本终止块
Terminating blocks of multiline text in Xtext/ANTLR
我开始掌握 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))
}
都通过了!
我开始掌握 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))
}
都通过了!