【问题标题】:How to tokenize this?如何标记这个?
【发布时间】:2017-11-21 00:36:10
【问题描述】:

我正在尝试手动编写标记器。我继续阅读可以成为令牌一部分的字符。例如整数只能包含数字。因此,在下面的文本中,我继续阅读字符,直到找到一个非数字字符。所以我得到 123 作为令牌。接下来我得到 ( 作为标记,然后是 abc 作为标识符。这很好,因为 ( 是一个分隔符。

123(abc

但是,在下面的文本中,我将 123 作为整数,然后将 abc 作为标识符。但实际上这无效,因为它们之间没有分隔符。

123abc(

标记器是否应该检查分隔符并报告错误?如果是,应该返回什么标记,在找到无效标记后标记器应该从哪里继续读取?

或者标记器是否应该简单地将 123 作为整数返回,并将 abc 作为标识符返回并让解析器检测错误?

【问题讨论】:

    标签: lexical-analysis


    【解决方案1】:

    通常,分词器(或lexer)不检查有效语法。

    词法分析器的作用是将输入拆分为标记,然后可以通过parser 将其转换为语法树。因此,执行此类检查通常是解析器的工作。

    【讨论】:

      【解决方案2】:

      这在某种程度上是一个灰色区域,但大多数手动编码的词法分析器只是进行标记化,并让解析器决定标记流是否有意义。

      【讨论】:

      • 在这种情况下你可能会给出一个词法错误,因为123abc 不是一个标记。
      【解决方案3】:

      如果“123abc”是一个无效的令牌,那么您应该在发现它后立即处理它,因为它与令牌的定义方式直接相关,而不是它们如何相互交互(这将成为词法分析器的工作)。这是一个拼写错误,而不是与语法相关的错误。

      有多种方法可以解决:

      • 您可以中止解析并仅抛出一些异常,使调用者没有令牌或只有您在此之前成功解析的令牌。这将为您节省任何“恢复”逻辑,并且可能足以满足您的用例。虽然,例如,如果您正在解析语法突出显示的内容,这可能还不够,因为您不希望所有剩余代码看起来都未解析。

        示例:如果不需要处理格式错误的标记,符合标准的 XML 解析器可以将其用于致命错误,只需输出一个基本错误并退出。

      • 或者,您可以插入一个“错误”标记,其中包含有关错误性质的适当元数据,然后跳到下一个有效标记。

        您可能需要在词法分析器中使用启发式算法来优雅地处理错误标记,并找到在嵌套表达式中发现错误标记时如何解释进一步的标记(例如,您是否应该认为表达式已经结束?寻找结束令牌?等等)。

        无论如何,这种方法将允许使用错误标记来显示有关所遇到错误的位置和性质的精确信息(想想 GUI 中的内联错误报告)。

      【讨论】:

        【解决方案4】:

        您可以考虑生成分词器或词法分析器。 FlexANTLR 之类的工具应该会有所帮助。您还可以使用 ANTLR 或 Bison

        生成解析器

        如果您坚持对您的词法分析器(和您的解析器)进行手工编码,那么在实践中进行一些前瞻性是非常有帮助的。例如,您可以逐行读取输入并在当前行内进行标记(能够检查接下来的几个字符)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-14
          • 1970-01-01
          相关资源
          最近更新 更多