Frage

Ich habe einen Parser und Lexer in ocamlyacc und ocamllex geschrieben. Wenn die Datei endet vorzeitig zu analysieren, wie in I am Ende einer Zeile ein Semikolon vergessen, wird die Anwendung nicht einen Syntaxfehler erhöhen. Ich weiß, es ist, weil ich das Anheben und EOF zu kontrollieren und das macht die Lexer die unvollendete Regel ignorieren, aber wie sollte ich dies einen Syntaxfehler zu erhöhen tun?

Hier ist meine aktuellen Parser (vereinfacht),

%{
    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                         { []                    }

und lexxer (vereinfacht),

{
    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 }

Beispiel-Eingabedatei,

one = two, three, one-hundred;
single label;
list : command, missing, a, semicolon

Eine Lösung ist einen rekursiven Aufruf in der Befehls Regel hinzufügen am Ende zu sich selbst, und das Hinzufügen einer leeren Regel, die alle eine Liste zu erstellen, um das Hauptprogramm zurückzukehren. Ich glaube, ich vielleicht Eof als Erwartung interpretieren und Endbedingung, eher dann einen Fehler in der Lexer, dies richtig ist?

War es hilfreich?

Lösung

ocamlyacc nicht notwendigerweise den gesamten Eingang verbrauchen. Wenn Sie es zwingen, versagen wollen, wenn die gesamte Eingabe wird nicht analysieren-fähig, müssen Sie EOF in Ihrer Grammatik übereinstimmen. Stattdessen Eof in Sie Lexer zu heben, einen Token EOF hinzufügen und Ihr start Symbol ändern

%type <Conf.config list> main

main:
    EOF { [] }
  | command main { $1::$2 }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top