首页 > 其他分享 >5.8 Error recovery 错误恢复

5.8 Error recovery 错误恢复

时间:2025-01-05 14:12:55浏览次数:5  
标签:errors recovery 错误 5.8 Error 分析器 --- error

By default, the parser will stop as soon as it encounters an error. Sometimes though we would like to try and recover and keep going. LALRPOP can support this, but you have to help it by defining various "error recovery" points in your grammar. This is done by using a special ! token: this token only occurs when the parser encounters an error in the input. When an error does occur, the parser will try to recover and keep going; it does this by injecting the ! token into the stream, executing any actions that it can, and then dropping input tokens until it finds something that lets it continue.

MST --- 默认情况下,解析器将在遇到错误时立即停止。但有时我们想尝试恢复并继续前进。LALRPOP 可以支持这一点,但您必须通过在语法中定义各种 “错误恢复” 点来帮助它。这是通过使用特殊的 !token:仅当解析器在输入中遇到错误时,才会出现此令牌。当发生错误时,解析器将尝试恢复并继续运行;它通过注入 !token 添加到流中,执行它可以执行的任何操作,然后删除 input token,直到找到允许它继续的内容。

GPT --- 默认情况下,解析器会在遇到错误时立即停止。然而,有时我们希望尝试恢复并继续解析。LALRPOP 支持这一点,但需要你通过在语法中定义各种“错误恢复”点来帮助它。这是通过使用一个特殊的 ! 令牌来实现的:当解析器在输入中遇到错误时,这个令牌会出现。当错误发生时,解析器会尝试恢复并继续执行;它通过将 ! 令牌插入到输入流中,执行任何可以执行的动作,然后丢弃输入令牌,直到找到一个可以继续的地方。

Let's see how we can use error recovery to attempt to find multiple errors during parsing. First we need a way to return multiple errors as this is not something that LALRPOP does by itself so we add a Vec storing the errors we found during parsing. Since the result of ! contains a token, error recovery requires that tokens can be cloned. We need to replace the begin "grammar" line of the LALRPOP file with this:

MST --- 让我们看看如何使用错误恢复来尝试在解析过程中查找多个错误。首先,我们需要一种方法来返回多个错误,因为这不是 LALRPOP 自己做的事情,因此我们添加了一个 Vec 来存储我们在解析过程中发现的错误。由于 !包含 Token,则 Error Recovery 要求可以克隆 Token。我们需要将 LALRPOP 文件的 begin “grammar” 行替换为以下内容:

GPT --- 我们来看一下如何使用错误恢复来尝试在解析过程中找到多个错误。首先,我们需要一种方法来返回多个错误,因为 LALRPOP 默认并不会这样做,所以我们添加了一个 Vec 来存储在解析过程中找到的错误。由于 ! 的结果包含一个令牌,错误恢复要求令牌是可克隆的。因此,我们需要将 LALRPOP 文件的开头的 grammar 行替换为以下内容:

use lalrpop_util::ErrorRecovery;

grammar<'err>(errors: &'err mut Vec<ErrorRecovery<usize, Token<'input>, &'static str>>);

The ErrorRecovery struct wraps ParseError to add a second field referencing the skipped characters.

MST --- ErrorRecovery 结构包装 ParseError 以添加引用跳过字符的第二个字段。

GPT --- ErrorRecovery 结构体包装了 ParseError,并添加了一个第二个字段,用于引用被跳过的字符。

Since an alternative containing ! is expected to return the same type of value as the other alternatives in the production we add an extra variant to Expr to indicate that an error was found.

MST --- 由于包含 !预期返回与生产中的其他替代项相同类型的值,我们向 Expr 添加了一个额外的变体以指示发现错误。

GPT --- 由于包含 ! 的替代方案预期返回与该产生式中其他替代方案相同类型的值,因此我们向 Expr 中添加了一个额外的变体,用于指示找到错误。

pub enum Expr {
    Number(i32),
    Op(Box<Expr>, Opcode, Box<Expr>),
    Error,
}

Finally we modify the grammar, adding a third alternative containing ! which simply stores the ErrorRecovery value received from ! in errors and returns an Expr::Error. The value of the error token will be a ParseError value. You can find the full source in calculator7.

MST --- 最后,我们修改语法,添加包含 !它只存储从 !in errors 并返回 Expr::Error 。错误令牌的值将是 ParseError 值。您可以在 calculator7 中找到完整源代码。

GPT --- 最后,我们修改语法,添加一个包含 ! 的第三个替代方案,该方案简单地将从 ! 接收到的 ErrorRecovery 值存储在 errors 中,并返回一个 Expr::Error。错误令牌的值将是一个 ParseError 值。你可以在 calculator7 中找到完整的源代码。

Term: Box<Expr> = {
    Num => Box::new(Expr::Number(<>)),
    "(" <Expr> ")",
    ! => { errors.push(<>); Box::new(Expr::Error) },
};

Now we can add a test that includes various errors (e.g., missing operands). Note that now the parse method takes two arguments instead of one, which is caused by that we rewrote the "grammar" line in the LALRPOP file. You can see that the parser recovered from missing operands by inserting this ! token where necessary.

MST --- 现在我们可以添加一个包含各种错误(例如,缺少操作数)的测试。请注意,现在 parse 方法接受两个参数而不是一个参数,这是因为我们在 LALRPOP 文件中重写了 “grammar” 行。你可以看到,解析器通过插入这个 !token 的 intent 中。

GPT --- 现在,我们可以添加一个包含各种错误(例如,缺失操作数)的测试。请注意,现在 parse 方法接受两个参数,而不是一个,这是因为我们重写了 LALRPOP 文件中的 "grammar" 行。你可以看到,解析器通过在必要的位置插入 ! 令牌来从缺失的操作数中恢复。

#[test]
fn calculator7() {
    let mut errors = Vec::new();

    let expr = calculator7::ExprsParser::new()
        .parse(&mut errors, "22 * + 3")
        .unwrap();
    assert_eq!(&format!("{:?}", expr), "[((22 * error) + 3)]");

    let expr = calculator7::ExprsParser::new()
        .parse(&mut errors, "22 * 44 + 66, *3")
        .unwrap();
    assert_eq!(&format!("{:?}", expr), "[((22 * 44) + 66), (error * 3)]");

    let expr = calculator7::ExprsParser::new()
        .parse(&mut errors, "*")
        .unwrap();
    assert_eq!(&format!("{:?}", expr), "[(error * error)]");

    assert_eq!(errors.len(), 4);
}

Error recovery can only handle errors reported at the parser level, not the lexer level. This means that an "InvalidToken" error (or similar from a custom lexer) will not be recoverable. In order to recover from lexer errors, you can add an Error token to the lexer, and rather than returning a lexer error, return a valid Error token. A worked example for custom lexers is available in the book. The same approach will work for the built in lexer as well.

MST --- 错误恢复只能处理在解析器级别报告的错误,而不能处理词法分析器级别的错误。这意味着 “InvalidToken” 错误(或自定义词法分析器中的类似错误)将无法恢复。为了从词法分析器错误中恢复,您可以向词法分析器添加 Error 标记,而不是返回词法分析器错误,而是返回有效的 Error 标记。书中提供了自定义词法分析器的工作示例。同样的方法也适用于内置的词法分析器。

GPT --- 错误恢复只能处理解析器层面报告的错误,而不能处理词法分析器层面的错误。这意味着诸如“InvalidToken”错误(或来自自定义词法分析器的类似错误)将无法恢复。为了从词法分析器错误中恢复,你可以向词法分析器添加一个 Error 令牌,而不是返回词法分析错误,返回一个有效的 Error 令牌。有关自定义词法分析器的完整示例,可以参考书中的内容。同样的方法也适用于内置的词法分析器。

标签:errors,recovery,错误,5.8,Error,分析器,---,error
From: https://www.cnblogs.com/Tifahfyf/p/18653300

相关文章

  • Error: Attempted to call generateViewport() from the server (Next.js 15)
    Erroroccurredprerenderingpage"/".Readmore:https://nextjs.org/docs/messages/prerender-errorError:AttemptedtocallgenerateViewport()fromtheserverbutgenerateViewportisontheclient.It'snotpossibletoinvokeaclientfuncti......
  • Error occurred prerendering page "/_not-found".(Next.js 15)
    我们需要更新UserProfile.tsx组件,改用Next.js的Link组件而不是react-router-dom的Link组件。以下是解决方法:这样可以确保组件更好地适应Next.js的框架,避免不兼容的问题。#错误的代码'useclient'importReactfrom'react'import{Box,Avatar,Typography,......
  • [cause]: TypeError: e_.createContext is not a function (Next.js 15)
    开发Next.js项目遇到报错: [cause]:TypeError:e_.createContextisnotafunction 出现这个报错的原因是在Next.js项目中,在 ServerComponent 中使用了MUI组件,但是MUI组件没有做SSR适配就会导致这个报错。解决办法解决办法就是在文件顶部添加 useclient 声明,让......
  • vue - 解决报错 Error: error:0308010C:digital envelope routines::unsupported(Vue项
    问题说明在vue2、vue3项目开发中,执行rundev运行|runbuild打包时,Vue报错error:0308010C:digitalenveloperoutines::unsupported,很奇怪的错误,无论是打包编译还是正常运行测试,直接报错终止,并且更改node.js版本依旧无效,试了很多办法都不行,提供详细解决教程!其他教程都无......
  • 【已解决】运行onnxruntime-gpu时遇到RuntimeError问题
    问题描述在使用onnxruntime进行模型推理时希望使用GPU进行加速,但运行时出现RuntimeError具体报错如下:***************EPError***************EPErrorD:\a_work\1\s\onnxruntime\python\onnxruntime_pybind_state.cc:891onnxruntime::python::CreateExecutionProviderInst......
  • Vue3 启动报错:failed to load config from D:\file\vue\examination_front\vite.c
    今天在创建vue3项目的时候报错了一个启动开发服务器时遇到了一个构建错误 查询了一下,执行npm i的时候,他并没有帮我安装vitePSD:\file\vue\hello_vue3>npmlistvitehello_vue3@0.0.0D:\file\vue\hello_vue3└──(empty)最后执行安装,就能启动了PSD:\file\vue\h......
  • dlib 19.24.6 error
         dlib19.24.6pipinstalldlibCopyPIPinstructionsLatestversionReleased: Aug10,2024 Atoolkitformakingrealworldmachinelearninganddataanalysisapplications Navigation Projectdescription Release......
  • 解决微信二维码接口接口返回:errcode\":47001,\"errmsg\":\"data format error rid
    dataformaterrorrid问题:在php中使用curl调用微信二维码生成接口getwxacodeunlimit时得到错误响应信息:errcode\":47001,\"errmsg\":\"dataformaterrorrid:xxx在微信开发者社区看了几个帖子全是在胡说,还有width参数不能小于280这种,真是笑死。。。解决:最终确定原因是接......
  • SocketTask.onError
    SocketTask.onError(functionlistener)小程序插件:支持相关文档:网络使用说明、局域网通信功能描述监听WebSocket错误事件参数functionlistenerWebSocket错误事件的监听函数参数Objectres属性类型说明errMsgstring错误信息......
  • error: [chromium-rawptr] Use raw_ptr<T> instead of a raw pointer.
    1.直接禁用掉报错 RAW_PTR_EXCLUSION例如RAW_PTR_EXCLUSIONchar*bb 是一个宏,用于在Chromium中禁用某个特定的编译错误,特别是与使用原始指针(rawpointer)相关的错误。该错误提示你应该使用raw_ptr<T>而不是原始指针。2.如果不能使用base库的话,那么可以考虑使用 ......