2013-02-12 3 views
3

часто бывает удобно выражать грамматические постановки в BNF какПредставляющие эпсилон производств с FParsec парсеров комбинаторов

A ::= "car" 
    | "bike" 
    | ε 

где ε представляет собой пустое правило производства; т. е. нетерминал «А» может расширяться до терминалов «автомобиль», «велосипед» или ничего. Однако, если я не реорганизую свою грамматику, мне непонятно, как я буду представлять такую ​​грамматику в FParsec. Я знаю комбинатор «выбор», <|>, но насколько я знаю, нет «пустого» комбинатора. I.e., комбинатор, который возвращает true и не потребляет вход.

Я искал документацию FParsec высоко и низко, но я не нашел ничего, что делает это, что меня удивляет, потому что это похоже на общий сценарий. Я довольно новичок в FParsec (и вообще в комбинаторах), поэтому, возможно, я просто не использую правильные слова. Любые намеки?

ответ

3

Я думаю, что решение Джека должно сделать трюк для вас. Однако, если вы ищете примитив, который представляет собой синтаксический анализатор, который преуспевает, не потребляя никаких входных данных, то вы, вероятно, хотите preturn от FParsec.Primitives (см. preturn in the documentation).

Это может быть полезно, если вы комбинировали парсеры, которые строят значения некоторых AST вместо строк. Например, если у вас размеченное объединение:

type Vehicle = Car | Bike | Other 

Вы можете использовать pstring "car" >>% Car и pstring "bike" >>% Bike строить парсер, которые возвращают Vehicle значения. Тогда вы могли бы объединить их с помощью <|> и добавить специальный (пустой) случай с использованием preturn:

let parseA = 
    pstring "car" >>% Car <|> 
    pstring "bike" >>% Bike <|> 
    preturn Other 

Операция preturn, вероятно, не используется непосредственно очень часто, но это один из основных примитивов (потому что он определяет монадический единица или возвращение работа парсеров).

+0

Спасибо, что упомянул об этом, Томас. В самом деле, я впоследствии нашел и использовал 'preturn' после публикации вышеупомянутого вопроса. –

+1

Я только что заметил [это] (http://www.quanttec.com/fparsec/reference/primitives.html#members.:60::124::62::37 :) в документах fparsec - вы можете оптимизировать '<|> презерватив Другое' как' <|>% Другие'. –

1

Я не слишком знаком с FParsec - я обычно использую fsyacc - но что произойдет, если вы используете пустую строку с помощью комбинатора выбора? Например, что-то вроде:

let parseA = pstring "car" <|> pstring "bike" <|> pstring "" 
+0

Duh. Это случай переосмысления проблемы. Благодарю. –

Смежные вопросы