Parser / Lexer忽略不完整的语法规则

我有一个用ocamlyacc和ocamllex编写的解析器和词法分析器。如果要解析的文件过早结束,就像在行末尾忘记分号一样,应用程序不会引发语法错误。我意识到这是因为我正在提高并捕获EOF,这使得词法分析器忽略了未完成的规则​​,但是我应该怎么做才能引发语法错误? 这是我当前的解析器(简化),
%{
    let parse_error s = Printf.ksprinf failwith "ERROR: %s" s
%}

%token COLON
%token SEPARATOR
%token SEMICOLON
%token <string> FLOAT
%token <string> INT
%token <string> LABEL

%type <Conf.config> command
%start command
%%
  command:
      | label SEPARATOR data SEMICOLON    { Conf.Pair ($1,$3)     }
      | label SEPARATOR data_list         { Conf.List ($1,$3)     }
      | label SEMICOLON                   { Conf.Single ($1)      }
  label :
      | LABEL                             { Conf.Label $1         }
  data :
      | label                             { $1                    }
      | INT                               { Conf.Integer $1       }
      | FLOAT                             { Conf.Float $1         }
  data_list :
      | star_data COMMA star_data data_list_ending
                                          { $1 :: $3 :: $4        }
  data_list_ending:
      | COMMA star_data data_list_ending  { $2 :: $3              }
      | SEMICOLON                         { []                    }
和lexxer(简化),
{
    open ConfParser
    exception Eof
}

rule token = parse
    | ['t' ' ' 'n' '10' '13' '12']
                        { token lexbuf   }
    | ['0'-'9']+ ['.'] ['0'-'9']* ('e' ['-' '+']? ['0'-'9']+)? as n
                        { FLOAT n        }
    | ['0'-'9']+ as n   { INT n          }
    | '#'               { comment lexbuf }
    | ';'               { SEMICOLON      }
    | ['=' ':']         { SEPARATOR      }
    | ','               { COMMA          }
    | ['_' 'a'-'z' 'A'-'Z']([' ']?['a'-'z' 'A'-'Z' '0'-'9' '_' '-' '.'])* as w
                        { LABEL w        }
    | eof               { raise Eof      }

and comment = parse
    | ['#' 'n']        { token lexbuf   }
    | _                 { comment lexbuf }
示例输入文件,
one = two, three, one-hundred;
single label;
list : command, missing, a, semicolon
一种解决方案是在最后将命令规则中的递归调用添加到自身,并添加一个空规则,所有这些都构建一个列表以返回到主程序。我想我可能会将Eof解释为期望,结束条件,而不是词法分析器中的错误,这是正确的吗?     
已邀请:
ocamlyacc
不一定消耗整个输入。如果要在整个输入不可解析时强制它失败,则需要在语法中匹配
EOF
。而不是在你的词法分析器中提高
Eof
,添加一个令牌
EOF
并将你的
start
符号更改为
%type <Conf.config list> main

main:
    EOF { [] }
  | command main { $1::$2 }
    

要回复问题请先登录注册