Вопрос
Моя модель AST должна нести информацию о местоположении (имя файла, строка, индекс). Есть ли встроенный способ получить доступ к этой информации? Из справочных документов поток, кажется, несет позицию, но я бы предпочел, чтобы мне не приходилось реализовать фиктивного анализатора, чтобы сохранить позицию, и добавить это везде.
заранее спасибо
Решение
Парсеры фактически являются аббревиатурами типа для функций от потоков до ответов:
Parser<_,_> is just CharStream<_> -> Reply<_>
Имея это в виду, вы можете легко написать пользовательский анализатор для позиций:
let position : CharStream<_> -> Reply<Position> = fun stream -> Reply(stream.Position)
(* OR *)
let position : Parser<_,_> = fun stream -> Reply stream.Position
и информация о положении Atttach на все, что вы анализируете, используя
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