2009-06-25 14 views
6

http://www.cs.chalmers.se/Cs/Research/Language-technology/BNFC/Come posso definire una grammatica del file INI usando il BNFC?

come dovrei scrivere il mio BNF etichettato per ottenere BNFC per generare un parser INI per me?

Sono appena arrivato così lontano!

entrypoints File ; 

comment "#" ; 

token ID (letter | digit | ["-_'"])+ ; 

Ini. File ::= [Section] ; 
Sect. Section ::= "[" ID "]" [Statement] ; 
Bind. Statement ::= ID "=" ID ; 

separator Statement "\n" ; 
terminator Section "" ; 

[name] 
#x = 10 
y = 20 

Parse Successful! 

[Abstract Syntax] 

Ini [Sect (ID "name") [Bind (ID "y") (ID "20")]] 

[Linearized tree] 

[name]y = 20 

[name] 
x = 10 
#y = 20 

Parse Successful! 

[Abstract Syntax] 

Ini [Sect (ID "name") [Bind (ID "x") (ID "10")]] 

[Linearized tree] 

[name]x = 10 

o__O mi sono bloccato ...

+0

Che cosa vuoi fare dopo? Sembra che questo soddisfi le esigenze di analisi dei file ini –

+0

non proprio perché con le precedenti sezioni grammaticali può avere una sola associazione. Mi piacerebbe essere in grado di analizzare tutti i tipi di file INI. –

risposta

5

ho chiesto a uno degli sviluppatori BNFC e citare la sua risposta qui:

caratteri spaziali come nuove righe sono non sono ben supportate in gettoni, perché BNFC ha un tipo lexer hard-wired "spazio" . L'idea è che gli spazi non possono contenere il significato di nelle lingue "ben educate" . Una di queste restrizioni che ha reso BNFC così semplice ... ma dovresti essere in grado di risolvere questo problema utilizzando un preprocessore, ad es. linea di input parsing per linea.


Come per esempio:

entrypoints File ; 

comment "#" ; 

token ID (letter | digit | ["-_'"])+ ; 

Ini. File ::= [Section] ; 
Sect. Section ::= "[" ID "]" [Statement] ; 
Bind. Statement ::= ID "=" ID ; 

separator Statement "//" ; 
terminator Section "//" ; 

Leggi:

[name] 
x = 10 
y = 20 

Preprocessa:

012.
[name]// 
x = 10// 
y = 20// 

Parse:

Ini [Sect (ID "name") [Bind (ID "x") (ID "10"), Bind (ID "y") (ID "20")]] 

Trasformazione:

          ↓      ↓ 
Ini [Sect (ID "name") [Bind (ID "x") (ID "0"), Bind (ID "y") (ID "0")]] 

scrittura:

[name]// 
x = 0// 
y = 0// 

Postprocessa:

[name] 
x = 0 
y = 0 

(non selezionato, non so se funziona, solo per dare un'idea !!)