Я пытаюсь на данный момент держать мой лексер и парсер отдельно, основываясь на неопределенном совете книги Пролог и анализ естественного языка, который действительно не вдавался в подробности о lexing/tokenizing. Поэтому я даю ему шанс и вижу несколько незначительных проблем, которые указывают мне, что я вижу что-то очевидное.Prolog DCG: Написание языка программирования lexer
Все мои маленькие маркеры-парсеры, похоже, работают нормально; на данный момент это фрагмент моего кода:
:- use_module(library(dcg/basics)).
operator('(') --> "(". operator(')') --> ")".
operator('[') --> "[". operator(']') --> "]".
% ... etc.
keyword(array) --> "array".
keyword(break) --> "break".
% ... etc.
Это немного повторяющиеся, но это, кажется, работает. Тогда у меня есть некоторые вещи, которые мне не совсем нравится, и будет приветствовать предложения, но это похоже на работу:
Основное правило для моего Tokenizer это:
token(X) --> whites, (keyword(X) ; operator(X) ; id(X) ; int(X) ; string(X)).
Это не идеально; Я увижу, что int
разобрался в in,id(t)
, потому что keyword(X)
подходит к id(X)
. Поэтому я думаю, это первый вопрос.
Более важный вопрос, который у меня есть, заключается в том, что я не вижу, как правильно интегрировать комментарии в эту ситуацию. Я пробовал следующее:
skipAhead --> [].
skipAhead --> (comment ; whites), skipAhead.
comment --> "/*", anything, "*/".
anything --> [].
anything --> [_], anything.
token(X) --> skipAhead, (keyword(X) ; operator(X) ; id(X) ; int(X) ; string(X)).
Это не похоже на работу; аналитики, которые возвращаются (и я получаю много разборов), похоже, не оставили комментарий. Я нервничаю, что мое правило комментариев бесполезно неэффективно и, вероятно, вызывает много ненужного отступления. Я также нервничаю, что whites//0
из dcg/basics детерминирован; однако эта часть уравнения, похоже, работает, она просто интегрирует его с пропуском комментариев, который, похоже, не работает.
Как последнее замечание, я не вижу, как обращаться с распространенными ошибками разбора обратно пользователю с информацией о столбце/столбце. Похоже, мне пришлось бы отслеживать и пронизывать какую-то текущую информацию о строках/столбцах и записывать ее в токены, а затем, возможно, попытаться перестроить линию, если я захочу сделать что-то похожее на то, как это делает llvm. Является ли это честным или существует «рекомендуемая практика»?
Весь код может быть найден in this haste.
Хорошая причина для нервозности wrt. 'comment // 0':' фраза (комментарий, "/ **/* /") 'истинна, но скорее должна потерпеть неудачу. – false