Как определить грамматику файла INI с помощью BNFC?

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

как мне написать свой помеченный BNF, чтобы BNFC сгенерировал для меня синтаксический анализатор INI?

Я только что получил до сих пор о__О!

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

о__О я застрял...


person Cetin Sert    schedule 25.06.2009    source источник
comment
что ты хочешь делать дальше? Похоже, это в значительной степени удовлетворяет потребности в разборе файлов ini.   -  person a_m0d    schedule 25.06.2009
comment
не совсем потому, что с приведенной выше грамматикой разделы могут иметь только одинарную привязку. Я хотел бы иметь возможность анализировать все виды файлов ini.   -  person Cetin Sert    schedule 25.06.2009


Ответы (1)


Я спросил одного из разработчиков 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

(не проверял, не знаю, работает ли, просто для понимания!!)

person Cetin Sert    schedule 25.06.2009