How can I define an INI file grammar using the BNFC?
Asked Answered
K

1

7

http://www.cs.chalmers.se/Cs/Research/Language-technology/BNFC/

how should I write my labeled BNF to get BNFC to generate a INI parser for me?

I have only gotten so far o__O!

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 I'm stuck ...

Kenna answered 25/6, 2009 at 6:39 Comment(2)
What do you want to do next? Seems like this pretty much fulfills the needs for parsing ini filesSaleh
not really because with the above grammar sections can only have a single binding. I'd like to be able to parse all sorts of ini files.Kenna
K
6

I asked one of the BNFC devs and quote his reply here:

Space characters such as newlines are not well supported in tokens, because BNFC has a hard-wired lexer type "space". The idea is that spaces can't carry meaning in "well-behaved" languages. One of those restrictions that has made BNFC so simple... but you should be able solve this by using a preprocessor, e.g. parse input line by line.


Like for example:

entrypoints File ;

comment "#" ;

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

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

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

Read:

[name]
x = 10
y = 20

Preprocess:

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

Parse:

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

Transform:

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

Write:

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

Postprocess:

[name]
x = 0
y = 0

(not checked, don't know if it works, just to give an idea!!)

Kenna answered 25/6, 2009 at 11:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.