#f# #error-handling #fsyacc
#f# #обработка ошибок #fsyacc
Вопрос:
Я использую fsyacc / fslex из F # Power Pack для анализа некоторого исходного кода.
Для обнаружения ошибок я использую следующий код:
use inputChannel = new StreamReader(File.OpenRead tempFileName)
let lexbuf = Lexing.LexBuffer<_>.FromTextReader inputChannel
let ast = try
Parser.start Lexer.tokenize lexbuf
with e ->
let pos = lexbuf.EndPos
let line = pos.Line
let column = pos.Column
let message = e.Message
let lastToken = new System.String(lexbuf.Lexeme)
printf "Parse failed at line %d, column %d:n" line column
printf "Last loken: %s" lastToken
printf "n"
exit 1
Но когда этот код выдает сообщение об ошибке при синтаксическом анализе многострочного исходного файла, я получаю неправильную позицию строки и столбца:
Parse failed at line 0, column 10899:
Как я могу правильно получить номер строки, в которой произошла ошибка?
Комментарии:
1. Почему бы не отладить его? Также вы можете добавить проект fslex для его отладки
Ответ №1:
Во время лексики вам необходимо вручную увеличить номер строки с помощью правила, подобного
...
let newline = ('n' | 'r' 'n')
rule tokenize = parse
| newline { lexbuf.EndPos <- lexbuf.EndPos.NextLine; tokenize lexbuf }
...
Комментарии:
1. Да, у меня есть такое правило для lexer.
2. Хм, возможно, ваш регистр новой строки по какой-то причине не соответствует — сложно отлаживать лексику fslex, но я бы дважды проверил, что ваши фактические новые строки верны для вашего регулярного выражения новой строки. И, может быть, вы можете добавить оператор printf, чтобы узнать, действительно ли вы переходите в регистр новой строки (возможно, вы никогда не достигнете его из-за более раннего правила, использующего токен новой строки?)
3. Да, вы были правы. Я повредил новые строки перед синтаксическим анализом. Спасибо 🙂