2009-09-18 88 views
4

我有一個解析器和詞法分析器,用ocamlyacc和ocamllex編寫。如果要解析的文件過早結束,如我在行尾忘記了分號,則應用程序不會引發語法錯誤。我意識到這是因爲我正在提高和捕捉EOF,這使得詞法分析器忽略了未完成的規則​​,但是我應該怎樣做才能引發語法錯誤?解析器/ Lexer忽略不完整的語法規則

這是我的當前解析器(簡化的),

%{ 
    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解釋爲期望,結束條件,而不是詞法分析器中的錯誤,這是正確的嗎?

回答

5

ocamlyacc不一定消耗整個輸入。如果你想強制它失敗,如果整個輸入不能解析,你需要在你的語法中匹配EOF。相反,在你詞法分析器提高Eof,加令牌EOF和改變你的start符號

%type <Conf.config list> main 

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

是的,這是解決方案。我在玩弄EOF並在語法中建立一個列表,但是你是對的。謝謝克里斯。 – nlucaroni 2009-09-18 20:52:46