问题描述
class emmaGrammarDeFinition extends GrammarDeFinition {
const emmaGrammarDeFinition();
Parser start() => ref(value).plus().end();
Parser token(Object source,[String name]) {
if (source is String) {
return source.toParser(message: 'Expected ${name ?? source}').trim();
} else if (source is Parser) {
ArgumentError.checkNotNull(name,'name');
return source.flatten('Expected $name').trim();
} else {
throw ArgumentError('UnkNown token type: $source.');
}
}
Parser word() =>
ref(wordToken) &
(whitespace().plus() | ref(token,'.') | whitespace()).optional();
Parser call() =>
ref(wordToken) & ref(token,'(') & ref(value) & ref(token,')');
Parser array() =>
ref(token,'[') & ref(elements).optional() & ref(token,']');
Parser elements() =>
ref(value).separatedBy(ref(token,','),includeSeparators: false);
Parser members() =>
ref(pair).separatedBy(ref(token,includeSeparators: false);
Parser object() =>
ref(token,'{') & ref(members).optional() & ref(token,'}');
Parser pair() => (ref(wordToken)| ref(stringToken)) & ref(token,':') & ref(value);
Parser value() =>
ref(call) |
ref(word) |
ref(stringToken) |
ref(numberToken) |
ref(object) |
ref(array) |
ref(truetoken) |
ref(falsetoken) |
ref(nullToken);
Parser truetoken() => ref(token,'true');
Parser falsetoken() => ref(token,'false');
Parser nullToken() => ref(token,'null');
Parser stringToken() => ref(token,ref(stringPrimitive),'string');
Parser numberToken() => ref(token,ref(numberPrimitive),'number');
Parser wordToken() => ref(token,ref(wordPrimitive),'word');
Parser characterPrimitive() =>
ref(characternormal) | ref(characterEscape) | ref(characterUnicode);
Parser characternormal() => pattern('^"\\');
Parser characterEscape() => char('\\') & pattern(jsonescapeChars.keys.join());
Parser characterUnicode() => string('\\u') & pattern('0-9A-Fa-f').times(4);
Parser numberPrimitive() =>
char('-').optional() &
char('0').or(digit().plus()) &
char('.').seq(digit().plus()).optional() &
pattern('eE')
.seq(pattern('-+').optional())
.seq(digit().plus())
.optional();
Parser wordPrimitive() => letter().plus() & digit().plus().optional();
Parser stringPrimitive() =>
char('"') & ref(characterPrimitive).star() & char('"');
}
它很接近,但我对普通文本部分有一些问题。当我想映射这些点时,点就在那里,但缺少白色空间。
Parser word() => super.word().map((each) => WordValueWidget(each));
当我解析“Hello World”时。每个是第一个 ["Hello",null] 然后是 ["World","."] 我希望它是第一个 ["Hello"," "] 然后是 ["World","."]。
感谢您的帮助并为我的英语不好表示抱歉:)
解决方法
我怀疑 wordToken
已经消耗了单词字符之后的所有空格(由于您的令牌定义中的 .trim()
操作)。然后 whitespace().plus() | ref(token,'.') | whitespace()
中的所有选项都不匹配,.optional()
返回 null
。
也就是说,从像您发布的那样庞大而复杂的语法中很难分辨出来。理想情况下,您会尝试将问题分解为更小、更易于管理的部分,然后可以独立进行测试和修复。一个最低限度可重复的示例将使我更容易提供一个直接适用的解决方案。