2017-09-29 5 views
1

Je suis en train d'apprendre comment analyser des programmes simples.La production d'ocaml menhir parser n'est jamais réduite

Ceci est mon lexer.

{ 
open Parser 
    exception SyntaxError of string 
} 

let white = [' ' '\t']+ 

let blank = ' ' 


let identifier = ['a'-'z'] 


rule token = parse 
    | white {token lexbuf} (* skip whitespace *) 
    | '-' { HYPHEN } 
    | identifier { 
    let buf = Buffer.create 64 in 
    Buffer.add_string buf (Lexing.lexeme lexbuf); 
    scan_string buf lexbuf; 
    let content = (Buffer.contents buf) in 
    STRING(content) 
    } 
    | _ { raise (SyntaxError "Unknown stuff here") } 

and scan_string buf = parse 
    | ['a'-'z']+ { 
    Buffer.add_string buf (Lexing.lexeme lexbuf); 
    scan_string buf lexbuf 
    } 
    | eof {() } 

Mon "ast":

type t = 
    String of string 
    | Array of t list 

Mon analyseur:

%token <string> STRING 
%token HYPHEN 

%start <Ast.t> yaml 
%% 

yaml: 
    | scalar { $1 } 
    | sequence {$1} 
    ; 

sequence: 
    | sequence_items { 
    Ast.Array (List.rev $1) 
    } 
    ; 

sequence_items: 
    (* empty *) { [] } 
    | sequence_items HYPHEN scalar { 
    $3::$1 

    }; 

scalar: 
    | STRING { Ast.String $1 } 
    ; 

Je suis actuellement à un point où je veux analyser soit 'cordes' simples, à savoir some text ou «tableaux» de «chaînes», c'est-à-dire - item1 - item2.

Lorsque je compile l'analyseur avec Menhir je reçois:

Warning: production sequence -> sequence_items is never reduced. 
Warning: in total, 1 productions are never reduced. 

Je suis assez nouveau pour l'analyse syntaxique. Pourquoi cela n'est-il jamais réduit?

Répondre

2

Vous déclarez que votre point d'entrée à l'analyseur est appelé main

%start <Ast.t> main 

Mais je ne vois pas la production main dans votre code. Peut-être que le point d'entrée est censé être yaml? Si cela est modifié, l'erreur persiste-t-elle?


Aussi, essayez d'ajouter EOF jeton à votre lexer et à la production d'entrée de gamme, comme ceci:

parse_yaml: yaml EOF { $1 } 

Voir ici par exemple: https://github.com/Virum/compiler/blob/28e807b842bab5dcf11460c8193dd5b16674951f/grammar.mly#L56

Le lien vers le monde réel OCaml ci-dessous explique également comment utiliser EOL-je pense que cela va résoudre votre problème. A propos, vraiment cool que vous écriviez un analyseur YAML dans OCaml. Si elle est faite en open source, elle sera vraiment utile à la communauté. Notez que YAML est sensible à l'indentation, donc pour l'analyser avec Menhir, vous devrez produire une sorte de jeton INDENT et DEDENT par votre lexer. En outre, YAML est un surensemble strict de JSON, ce qui signifie qu'il pourrait (ou non) avoir un sens pour commencer avec un sous-ensemble JSON et ensuite le développer. OCaml Real World montre comment écrire un analyseur JSON en utilisant Menhir:

https://dev.realworldocaml.org/16-parsing-with-ocamllex-and-menhir.html

+0

Je renomme '' yaml' à main', parce que c'est le début de l'analyseur YAML et je suis déjà aux prises avec les bases . : D Le problème de réduction provient de la variante 'yaml'. Je vais essayer d'étudier realworldocaml. – Seneca

+0

@Seneca voir ma réponse mise à jour. – Halst

+0

Merci, c'est bien l'EOF qui l'a fait! – Seneca