2009-12-19 15 views
15

Ocamlyacc ve ocamllex kullanıyorum. Dilbilgimde özel bir istisna sinyali veren bir hata üretimim var. Ben de okundu hangi belirteç bilmek istiyorum,ocamlyacc ayrıştırma hatası: ne belirteli?

| error { raise (Parse_failure (string_of_position (symbol_start_pos()))) } 

Ama: Şimdiye kadar, ben hata konumunu bildirmek alabilirsiniz. Bir yolu olmalı --- kim bilir?

Teşekkürler.

cevap

14

Jeton hata oluştuğunda dolayısıyla mevcut lexer belirteci kullanabilirsiniz, lexer tarafından oluşturulmaktadır:

let parse_buf_exn lexbuf = 
    try 
     T.input T.rule lexbuf 
    with exn -> 
     begin 
     let curr = lexbuf.Lexing.lex_curr_p in 
     let line = curr.Lexing.pos_lnum in 
     let cnum = curr.Lexing.pos_cnum - curr.Lexing.pos_bol in 
     let tok = Lexing.lexeme lexbuf in 
     let tail = Sql_lexer.ruleTail "" lexbuf in 
     raise (Error (exn,(line,cnum,tok,tail))) 
     end 

Lexing.lexeme lexbuf ne ihtiyaç vardır. Diğer parçalar gerekli değil ama yararlıdır. ruleTail, kalan tüm simgeleri, kullanıcının hata konumunu kolayca bulması için dizeye ekleyecektir. Doğru konumlar içerecek şekilde lexer'da lexbuf.Lexing.lex_curr_p güncellenmelidir. Bu da geçer bu ayrıştırıcı baskısını bütün devletleri yapacak ve her vardiya/gerçekleştirdiği azaltmak - (source)

+0

Harika cevap. Yine de bir sorum var: neden lexbuf.lex_curr_p 'yerine lexbuf.Lexing.lex_curr_p' kullanmak zorundayız? – GiantSquid

+0

Çünkü 'lex_curr_p'' Lexing' modülüne aittir. Ya açmak veya OCaml daha akıllı hale gelene kadar beklemek ve niteliksiz kayıt alanı referanslarını anlamak. – ygrek

+2

Sql_lexer'ı nerede bulabilirsiniz. ve Hata? –

2

Sanırım, yacc'e benzer şekilde, belirteçleri gramer kuralınızdaki sembollere karşılık gelen değişkenlerde saklanır. Burada bir sembol (hata) bulunduğundan, printf, vb. Kullanarak 1 $ çıktırabilirsiniz.

Düzenleme: yoruma yanıt.

Neden bir hata terminali kullanıyorsunuz? Ayrıştırma hatası oluştuğunda özel bir hata işleme rutininin çağrıldığını söyleyen bir ocamlyacc öğreticisini okuyorum. böylece gibi:

3.1.5. The Error Reporting Routine

When ther parser function detects a syntax error, it calls a function named parse_error with the string "syntax error" as argument. The default parse_error function does nothing and returns, thus initiating error recovery (see Error Recovery). The user can define a customized parse_error function in the header section of the grammar file such as:

let parse_error s = (* Called by the parser function on error *) 
    print_endline s; 
    flush stdout 

Eh, yalnızca olsa o fonksiyonu ile "sözdizimi hatası" almak gibi görünüyor. Daha fazla bilgi için bizi takip etmeye devam edin.

+1

, çalışmaz: Eğer bash kullanıyorsanız

, aşağıdaki komutu ile yapabilirsiniz argüman –

+1

olan error ', tüm fonksiyonun kodunu gösterebilir misiniz? O zaman daha fazla bilgi sunabilirim. – danben

19

sizin ocamlyacc ayrıştırıcı hata ayıklamak için en iyi yolu karakteri p içerecek şekilde OCAMLRUNPARAM param ayarlamaktır. 1 $ `terminali ifade eder: çizgi 372 "parser.mly" Dosya: Maalesef

$ export OCAMLRUNPARAM='p'