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

Cet*_*ert 6 parsing haskell bnf ebnf context-free-grammar

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 "" ;
Run Code Online (Sandbox Code Playgroud)
[name]
#x = 10
y = 20
Run Code Online (Sandbox Code Playgroud)
Parse Successful!

[Abstract Syntax]

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

[Linearized tree]

[name]y = 20
Run Code Online (Sandbox Code Playgroud)
[name]
x = 10
#y = 20
Run Code Online (Sandbox Code Playgroud)
Parse Successful!

[Abstract Syntax]

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

[Linearized tree]

[name]x = 10
Run Code Online (Sandbox Code Playgroud)

我被困了......

Cet*_*ert 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 "//" ;
Run Code Online (Sandbox Code Playgroud)

读:

[name]
x = 10
y = 20
Run Code Online (Sandbox Code Playgroud)

预处理:

[name]//
x = 10//
y = 20//
Run Code Online (Sandbox Code Playgroud)

解析:

Ini [Sect (ID "name") [Bind (ID "x") (ID "10"), Bind (ID "y") (ID "20")]]
Run Code Online (Sandbox Code Playgroud)

转变:

                                          ?                       ?
Ini [Sect (ID "name") [Bind (ID "x") (ID "0"), Bind (ID "y") (ID "0")]]
Run Code Online (Sandbox Code Playgroud)

写:

[name]//
x = 0//
y = 0//
Run Code Online (Sandbox Code Playgroud)

后期过程:

[name]
x = 0
y = 0
Run Code Online (Sandbox Code Playgroud)

(没有检查,不知道它是否有效,只是为了给出一个想法!!)