首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ocamlyacc出现详细错误

ocamlyacc出现详细错误
EN

Stack Overflow用户
提问于 2012-12-27 05:18:45
回答 2查看 2.6K关注 0票数 2

在bison中,只需添加

代码语言:javascript
复制
%verbose-error 

以使解析器错误更加详细。有没有办法用ocamlyacc获得类似的功能?

Here是一个类似问题的答案,但我无法理解它。下面是我调用lexer和parser函数的方式:

代码语言:javascript
复制
let rec foo () =
    try
    let line = input_line stdin in
    (try
       let _ = (Parser.latexstatement lexer_token_safe (Lexing.from_string line)) in
         print_string ("SUCCESS\n")
     with
           LexerException s          -> print_string ("$L" ^ line ^ "\n")
         | Parsing.Parse_error       -> print_string ("$P" ^ line ^ "\n")
         | _                         -> print_string ("$S " ^ line ^ "\n"));
    flush stdout;
    foo ();
    with
    End_of_file -> ()
;;
foo ();;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-27 10:41:22

我不认为ocamlyacc中有一个选项可以自动执行您想要做的事情,所以让我尝试在下面提供一个完整的描述,说明可以做些什么来处理语法错误并获得更有用的消息。也许这不是你所要求的。

错误实际上必须在词法错误和解析错误中分开,这取决于错误发生在解析过程的哪个阶段。

  • mll文件中,如果mly文件中的
  • 出现意外模式,将引发Failure异常,它是Parsing.Parse_error异常,将由<

>F29生成

因此,您有几种解决方案:

  • 允许词法分析器和解析器代码引发它们的异常,并在调用它们的代码中捕获它们。使用
    • 为词法分析器提供一个catch all规则(或者,如果在解析器规则中使用error特殊终端来捕获特定places

中的错误,则还可以使用一些更特定的模式)来捕获它们中的错误

在任何情况下,您都必须创建函数来获取有关错误在源中的位置的信息。LexingParsing都使用在Lexing中定义的具有以下字段的location记录:

  • pos_fname :当前文件的名称processed
  • pos_lnum :文件中的行号
  • pos_bol:从文件开头到line
  • pos_cnum开头的字符号:当前位置的字符号

lexer使用的lexbuf变量有两个类似的值,用于跟踪正在进行词法分析的当前标记( Lexing中的lexeme_start_plexeme_curr_p允许您访问这些数据)。解析器有四个跟踪要合成的当前符号(或非终结符)和当前规则项,可以使用Parsing函数(rhs_start_posrhs_end_pos,以及symbol_start_possymbol_end_pos)检索当前规则项。

下面是一些生成更详细异常的函数:

代码语言:javascript
复制
exception LexErr of string
exception ParseErr of string

let error msg start finish  = 
    Printf.sprintf "(line %d: char %d..%d): %s" start.pos_lnum 
          (start.pos_cnum -start.pos_bol) (finish.pos_cnum - finish.pos_bol) msg

let lex_error lexbuf = 
    raise ( LexErr (error (lexeme lexbuf) (lexeme_start_p lexbuf) (lexeme_end_p lexbuf)))

let parse_error msg nterm =
    raise ( ParseErr (error msg (rhs_start_p nterm) (rhs_end_p nterm)))

以及一些基本用例:

解析器:%token错误

代码语言:javascript
复制
/* ... */

wsorword:
    WS                 { $1 }
  | WORD            { $1 }
  | error             { parse_error "wsorword" 1; ERR "" } /* a token needed for typecheck */
;

lexer:

代码语言:javascript
复制
rule lexer = parse
(*  ... *)
(* catch all pattern *)
| _                      { lex_error lexbuf }

剩下的工作就是修改您的顶级函数来捕获异常并处理它们。

最后,出于调试目的,Parsing中提供了一个set_trace函数,该函数支持解析引擎使用的状态机的显示消息:它跟踪自动机的所有内部状态更改。

票数 11
EN

Stack Overflow用户

发布于 2017-05-21 00:36:32

Parsing模块(您可以在here中查看它)中有一个函数Parsing.set_trace,它将执行此操作。您可以像这样使用它:Parsing.set_trace True来启用。此外,您可以使用-v参数运行ocamlyacc,它将输出一个.output,其中列出了所有状态和换位。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14046392

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档