Информация о положении в fparsec - PullRequest
5 голосов
/ 15 июня 2011

Моя модель AST должна содержать информацию о местоположении (имя файла, строка, индекс).Есть ли какой-нибудь встроенный способ доступа к этой информации?Из справочных документов поток, по-видимому, несет позицию, но я бы предпочел, чтобы мне не приходилось реализовывать фиктивный парсер, чтобы просто сохранить позицию и добавлять ее везде.

Заранее спасибо

1 Ответ

8 голосов
/ 15 июня 2011

Парсеры на самом деле являются сокращениями типов для функций из потоков в ответы:

Parser<_,_> is just CharStream<_> -> Reply<_>

Имея это в виду, вы можете легко написать собственный анализатор для позиций:

let position : CharStream<_> -> Reply<Position> = fun stream -> Reply(stream.Position)
(* OR *)
let position : Parser<_,_> = fun stream -> Reply stream.Position

и привязывать информацию о положении к каждому биту, который вы анализируете с помощью

position .>>. yourParser (*or tuple2 position yourParser*)

анализатор положения не потребляет никакого ввода, и таким образом его можно безопасно комбинировать таким образом.

Вы можете сохранить требуемое изменение кода ограниченным одной строкой и избежать неконтролируемого распространения кода:

type AST = Slash of int64
         | Hash  of int64

let slash : Parser<AST,_> = char '/' >>. pint64 |>> Slash
let hash  : Parser<AST,_> = char '#' >>. pint64 |>> Hash
let ast   : Parser<AST,_> = slash <|> hash

(*if this is the final parser used for parsing lists of your ASTs*)
let manyAst  : Parser<            AST  list,_> = many                (ast  .>> spaces)

let manyAstP : Parser<(Position * AST) list,_> = many ((position .>>. ast) .>> spaces)
(*you can opt in to parse position information for every bit
  you parse just by modifiying only the combined parser     *)

Обновление : FParsec имеет предопределенный парсер для позиций: http://www.quanttec.com/fparsec/reference/charparsers.html#members.getPosition

...