http://stackoverflow.com/questions/9556 ... 30#9556530
Я могу описать это на любом уровне детализации вы заботитесь, чтобы назвать, но у меня нет времени для более краткого объяснения. Я объясню, как мы делаем это в Рослин.
Во-первых, мы строим модель непреложный поток токенов, используя структуру данных, которые могут эффективно представлять изменения, так как очевидно, изменений как раз то, что там будет много.
Ключ понимания, чтобы сделать его эффективным для повторного использования является стойким, чтобы представить характер длина маркеров, но не их позиции символа в буфере редактирования, помните, что знак в конце файла не изменит позицию по каждой редактирования но длина из маркера не меняется. Вы должны любой ценой минимизировать общее число повторно lexings, если вы хотите, чтобы быть эффективным на очень больших файлов.
Если у вас есть модель, неизменный, который может обрабатывать вставки и удаления, чтобы создать поток неизменный знак без повторного лексический весь файл каждый раз, затем вы должны сделать то же самое, но для грамматического анализа. Это на практике значительно более трудная задача. Я рекомендую вам получить бакалавра или ученую степень в области компьютерных наук с акцентом на анализатор теории, если вы еще этого не сделали. Мы получили помощь от людей с докторской степенью, кто сделал диссертации по теории синтаксического анализатора для разработки данного бит алгоритма.
Тогда, очевидно, построить грамматический анализатор, который может анализировать C #. Помните, что необходимо проанализировать сломанной C #, а не правильное C #; IntelliSense должен работать, пока программа не в состоянии компиляции. Таким образом, начать придумывать изменения в грамматике, которые имеют хорошие ошибка восстановления характеристик.
Итак, теперь у вас есть парсер, который может эффективно делать грамматический анализ без повторного лексический или повторного разбора все, но раз редактировалось области, большую часть времени, что означает, что вы можете сделать работу между нажатиями клавиш. Я забыл упомянуть, конечно, вам нужно придумать какой-то механизм, чтобы не блокировать поток пользовательского интерфейса, делая все эти анализы должны анализа случиться дольше, чем время между двумя нажатиями клавиш. Новый «асинхронный / ждут" особенность C # 5 должна помочь в этом. (Я могу вам сказать из личного опыта: будьте осторожны с распространением задач и отмена жетоны Если вы небрежно, можно попасть в состояние, в котором есть десятки тысяч отменен задач в ожидании, и это не быстро.. )
Теперь, когда у вас есть грамматического анализа необходимо построить семантический анализатор. Поскольку вы только делаете IntelliSense, не нужно быть особенно сложным семантический анализатор. (Наш семантический анализатор должен делать анализ пригоден для генерации кода из правильных программ и правильный анализ ошибок с неправильной программы.) Но, конечно, опять же он должен делать добро семантический анализ на сломанной программы, которые действительно увеличивает сложность значительно.
Мой совет: начните с создания "высшего уровня" семантический анализатор, снова используя модель неизменным, которые могут сохраняться состояние объявленных в своем исходном коде типы из редактирования изменить. Верхний анализатор уровня занимается всем, что не является оператор или выражение: объявления типа, директивы, пространства имен, объявления методов, конструкторы, деструкторы, и так далее. Материал, который составляет «форму» программы, когда компилятор генерирует метаданные.
Метаданные! Я забыл о метаданных. Вы будете нуждаться в метаданных читатель. Вы должны быть в состоянии произвести IntelliSense для выражений, которые относятся к типам в библиотеках, очевидно. Я рекомендую использовать ТПП библиотеки качестве метаданных читатель, а не отражение. Поскольку вы только делаете IntelliSense, очевидно, не нужно метаданных писателя.
Во всяком случае, когда у вас есть на высшем уровне семантический анализатор, то вы можете написать заявление и выражения семантический анализатор, который анализирует типы выражений в данном заявлении. Обратите особое внимание на поиск имени и алгоритмы разрешения перегрузки. Метод вывода типа будет особенно сложно, особенно внутри запросов LINQ.
После того как вы получили все, что IntelliSense двигателя должно быть легко, просто выработать тип выражения в текущую позицию курсора и отображения выпадающего соответственно.
Как трудно было бы для меня, чтобы создать свой собственный одного и того же стандарта?
Ну, у нас есть команда, назовем его десять человек, и это, наверное, взять, назовем его пять лет все вместе, чтобы получить все это делается от начала до конца. Но у нас много больше делать, чем просто IntelliSense двигателя. Это может быть, только 40% работы. Ох, и половина этих людей работать на VB, теперь, когда я думаю об этом. Но те люди, в среднем, вероятно, пять или десять лет опыта в ведении такого рода работы, поэтому они быстрее, чем вы будете, если вы никогда не делали этого раньше.
Так скажем, это займет у вас от десяти до двадцати лет полный рабочий день, работая в одиночку, чтобы построить Рослин качества IntelliSense двигатель для C #, который может сделать приемлемо, близкие к правильным анализа больших программ во время между нажатиями клавиш.
Больше, если вам нужно сделать, что кандидат во-первых, это очевидно.
Или вы могли бы просто использовать Рослин, так это то, что он нужен. Вот возьмем вы, вероятно, несколько часов, но вы не получаете удовольствия от делать это самостоятельно. И это весело!