문제

나는 Ocamlyacc와 Ocamllex로 작성된 파서와 Lexer가 있습니다. 라인 끝에서 세미콜론을 잊어 버린 것처럼 구문 분석 파일이 조기에 종료되면 응용 프로그램은 구문 오류가 발생하지 않습니다. 나는 그것이 내가 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' '\010' '\013' '\012']
                        { 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를 기대와 결말 조건으로 해석하는 것을 Lexer의 오류로 해석한다고 생각합니다. 이것이 맞습니까?

도움이 되었습니까?

해결책

ocamlyacc 반드시 전체 입력을 소비하지는 않습니다. 전체 입력을 구문 분석 할 수없는 경우 실패하도록 강요하려면 일치해야합니다. EOF 당신의 문법에서. 제기 대신 Eof 렉서에 토큰을 추가하십시오 EOF 그리고 당신의 변화 start 상징

%type <Conf.config list> main

main:
    EOF { [] }
  | command main { $1::$2 }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top