Ошибка: генерирует пустой язык, используя Menhir и OCaml

В настоящее время я работаю над Pascal Parser, используя OCaml и Menhir. Когда я компилирую свой parser.mly, который содержит следующий скриптлет, Менгир просто говорит: "Предупреждение: if_cmd генерирует пустой язык". Это может произойти, когда правило "if_cmd" не может быть достигнуто из исходного (поправьте меня, если я Я ошибаюсь), но по логике вещей, это должно было быть достигнуто. Я не могу понять, почему происходит это предупреждение. Например, если я использую входной файл для грамматики, указанной в parser.mly с этими операторами:

program ex1; 
x:=1
y:=(2)

это дает мне желаемый ответ. Но если я использую это в качестве ввода

program ex1; 
x:=1
y:=(2)
if(x and 2) then
   y:=3

Говорится Exception: Syntax.Errorвероятно из-за этого предупреждения

С этими 4 следующими файлами в одной папке, я использовал ocamlbuild -use-menhir main.byte команда, которая генерирует только что упомянутое предупреждение

lexer.mll

{
   open Lexing
   open Printf
   open Parser

   let incr_line_number lexbuf = 
   let pos = lexbuf.lex_curr_p in
             lexbuf.lex_curr_p <- { pos with
             pos_lnum = pos.pos_lnum + 1;
             pos_bol = pos.pos_cnum;
            }
}


let digit = ['0' - '9']
let integer = digit+

let letter = ['a' - 'z' 'A' - 'Z']
let identifier = letter ( letter | digit | '_')*

let blank = [' ' '\t']+
let newLine = '\r' | '\n' | "\r\n"

rule token = parse
  blank    { token lexbuf }
| newLine  { incr_line_number lexbuf; token lexbuf }
| integer as num { let number = int_of_string num in 
                LITINT number  }
| '('                            { OPENPAR }
| ')'                            { CLOSEPAR }
| ';'                            { SEMICOLON }
| "program " + identifier as id  { PROGRAM (id) }
| "begin"                        { BEGIN }
| "end"                          { END }
| "if"                           { IF }
| "then"                         { THEN }
| "else"                         { ELSE }
| ":="                           { ASSIGN }
| "and"                          { AND }
| "or"                           { OR } 
| identifier as id               { ID id }
| eof                            { EOF }

parser.mly

%{
  open Ast (* Abstract Syntax Tree*)
%}

%token <int> LITINT
%token <string> PROGRAM
%token <string> ID
%token BEGIN END
%token SEMICOLON
%token ASSIGN
%token IF THEN ELSE
%token OPENPAR CLOSEPAR
%token AND OR
%token EOF

%left OR
%left AND

%start program
%type <Ast.program> program

%%

program: prog=PROGRAM SEMICOLON
      c = command*
      EOF
      { Program (prog, List.flatten c) }

command: c = assignment_cmd                     { c }
       | c = if_cmd                             { c }
       | BEGIN cs=command+ END SEMICOLON        { Block cs }

assignment_cmd: id = ID ASSIGN e = expression { AssignmentCmd (id, e) }

if_cmd: IF e=expression THEN 
            c1=command
            s=option(ELSE c2=command {c2})
        { IfCmd (e, c1, s) }

expression: id=ID                           { ExpVar id }
     | i=LITINT                             { ExpInt i }
     | e1=expression op=oper e2=expression  { ExpOp (op, e1, e2) }
     | OPENPAR e=expression CLOSEPAR        { e }

%inline oper:
     | AND      { And }
     | OR       { Or }

ast.ml

type ident = string

type program = Program of ident * commands
and commands = command list
and command = AssignmentCmd of ident * expression
            | IfCmd of expression * command * (command option)
            | Block of commands

and expression = ExpVar of ident
               | ExpInt of int
               | ExpOp of oper * expression * expression

and oper = 
         | And
         | Or

main.ml

open Ast

let parse_file name =
                        let ic = open_in name in
                        let lexbuf = Lexing.from_channel ic in
                        let ast = Parser.program Lexer.token lexbuf in
                        let _ = close_in ic in
                        ast

0 ответов

Другие вопросы по тегам