문제

My AST model needs to carry location information (filename, line, index). Is there any built in way to access this information? From the reference docs, the stream seems to carry the position, but I'd prefer that I dont have to implement a dummy parser just to save the position, and add that everywhere.

Thanks in advance

도움이 되었습니까?

해결책

Parsers are actually type abbreviations for functions from streams to replies:

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

Keeping that in mind, you can easily write a custom parser for positions:

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

and atttach position information to every bit you parse using

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

position parser does not consume any input and thus it is safe to combine in that way.

You can keep the code change required restricted to a single line and avoid uncontrollable code spread:

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     *)

Update: FParsec has a predefined parser for positions: http://www.quanttec.com/fparsec/reference/charparsers.html#members.getPosition

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top