我的 PetitParser 映射函数中缺少空格

问题描述

我尝试解析包含函数调用的普通文本。

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

也就是说,从像您发布的那样庞大而复杂的语法中很难分辨出来。理想情况下,您会尝试将问题分解为更小、更易于管理的部分,然后可以独立进行测试和修复。一个最低限度可重复的示例将使我更容易提供一个直接适用的解决方案。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...