如何使用BNFC定义INI文件语法?

时间:2009-06-25 06:39:24

标签: parsing haskell bnf context-free-grammar ebnf

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

我该如何编写带标签的BNF以让BNFC为我生成INI解析器?

我到目前为止只有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我被卡住了......

1 个答案:

答案 0 :(得分:5)

我问其中一位BNFC开发者并在此引用他的回复:

  

换行符等空格字符   在令牌中得不到很好的支持,因为   BNFC具有硬连线词法分类器   “空间”。这个想法是空间不能   带有“乖巧”的意思   语言。其中一个限制   这让BNFC如此简单......但是   你应该能够通过使用来解决这个问题   预处理器,例如解析输入行   按行。


例如:

entrypoints File ;

comment "#" ;

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

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

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

读:

[name]
x = 10
y = 20

预处理:

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

解析:

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

变换:

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

写:

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

后处理:

[name]
x = 0
y = 0

(未经检查,不知道是否有效,只是为了提出一个想法!)