Парсеры и компиляторы для чайников. С чего начать? [дубликат]
этот вопрос уже есть ответ здесь:
- обучение написанию компилятора [закрыто] 40 ответов
Это хорошо список, но что является лучшим для полного новичка в этой области. Один для кого - то из более высокого уровня фона (VB6,C#,Java,Python) - не знаком с C или c++. Я гораздо больше интересует рукописный синтаксический анализ по сравнению с Lex / Yacc на этом этапе.
Если бы я просто специализировался в области компьютерных наук, а не психологии, я мог бы взять курс по этому в колледже. Ну что ж.
3 ответов
пожалуйста, посмотрите на:учимся писать компилятор
также интересно:
- как написать язык программирования
- парсинг где я могу узнать об этом
- учебные ресурсы по интерпретаторам и компиляторам синтаксических анализаторов (хорошо, вы уже упоминали об этом.
и есть еще на эту тему. Но я могу дать короткое введение:
первым шагом является лексический анализ. Поток символов преобразуется в поток токенов. Токены могут быть простыми, как = =
следующим шагом является перевод tokenstream в syntaxtree или другое представление. Это называется этапом синтаксического анализа.
прежде чем вы сможете создать парсер, вам нужно написать грамматику. Для пример создаем парсер выражений:
маркеры
addOp = '+' | '-';
mulOp = '*' | '/';
parLeft = '(';
parRight = ')';
number = digit, {digit};
digit = '0'..'9';
Each token can have different representations: + and = are both addOp and
23 6643 and 223322 are all numbers.
язык
exp = term | exp, addOp, term;
// an expression is a series of terms separated by addOps.
term = factor | term, mulOp, factor;
// a term is a series of factors separated by mulOps
factor = addOp, factor | parLeft, exp, parRight | number;
// a factor can be an addOp followed by another factor,
// an expression enclosed in parentheses or a number.
лексер
мы создаем механизм состояний, который проходит через поток char, создавая токен
s00
'+', '-' -> s01 // if a + or - is found, read it and go to state s01.
'*', '/' -> s02
'(' -> s03
')' -> s04
'0'..'9' -> s05
whitespace -> ignore and retry // if a whitespace is found ignore it
else ERROR // sorry but we don't recognize this character in this state.
s01
found TOKEN addOp // ok we have found an addOp, stop reading and return token
s02
found TOKEN mulOp
s03
found TOKEN parLeft
s04
found TOKEN parRight
s05
'0'..'9' -> s05 // as long as we find digits, keep collecting them
else found number // last digit read, we have a number
парсер
пришло время создать простой парсер / вычислитель. Это полный код. Обычно они создаются с помощью таблиц. Но мы сохраним его. простой. Прочитайте токены и вычислите результат.
ParseExp
temp = ParseTerm // start by reading a term
while token = addOp do
// as long as we read an addop keep reading terms
if token('+') then temp = temp + ParseTerm // + so we add the term
if token('-') then temp = temp - ParseTerm // - so we subtract the term
od
return temp // we are done with the expression
ParseTerm
temp = ParseFactor
while token = mulOp do
if token('*') then temp = temp * ParseFactor
if token('/') then temp = temp / ParseFactor
od
return temp
ParseFactor
if token = addOp then
if token('-') then return - ParseFactor // yes we can have a lot of these
if token('+') then return ParseFactor
else if token = parLeft then
return ParseExpression
if not token = parRight then ERROR
else if token = number then
return EvaluateNumber // use magic to translate a string into a number
Это был простой пример. В реальных примерах вы увидите, что обработка ошибок является большой частью парсера.
надеюсь, это немного прояснилось; -).
Если вы полный n00b, самый доступный ресурс (в обоих смыслах этого термина), вероятно, учебник Джека Креншоу. Это далеко не полный, но для начала я не могу придумать ничего близкого, кроме книг, которые давно вышли из печати.
Я хотел бы предложить статью, которую я написал под названием реализация языков программирования с использованием C# 4.0. Я пытался сделать его доступным для новичков. Он не является всеобъемлющим, но после этого должно быть легче понять другие более продвинутые тексты.