Значимые ошибки при синтаксическом анализе с помощью FSyacc

#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. Да, вы были правы. Я повредил новые строки перед синтаксическим анализом. Спасибо 🙂