Я использую утилиты fslex / fsyacc для своих F # Lexer и Parser. Если вводимый текст имеет неверный синтаксис, необходимо знать место, где это происходит.
Можно определить неправильную лексему (токен) в Lexer и выдать исключение, если использовался неправильный символ или слово:
rule token = parse
...
| integer { INT (Int32.Parse(lexeme lexbuf)) }
| "*=" { failwith "Incorrect symbol" }
| eof { EOF }
Вопрос больше относится к Parser (fsyacc) - если входной текст имеет правильные токены и был успешно токенизирован Lexer, но при синтаксическом анализе произошла ошибка (например, неправильный порядок токенов или какой-то отсутствующий токен в правиле)
Я знаю, если поймать исключение, это даст позицию (строку и столбец), где синтаксический анализ не удался:
try
Parser.start Lexer.token lexbuf
with e ->
let pos = lexbuf.EndPos
let line = pos.Line
let column = pos.Column
let message = e.Message // "parse error"
...
Но возможно ли (если да - как это сделать?) Определить также класс AST, для которого не удалось выполнить синтаксический анализ .
Например, можно ли написать что-то похожее на следующее в моем файле parser.fsy:
Expression1:
| INT { Int $1 }
...
| _ { failwith "Error with parsing in Expression1"}