Автор: Пользователь скрыл имя, 26 Февраля 2011 в 14:37, курсовая работа
Задачей данного курсового проекта является написание транслятора из языка высокого уровня С++ в язык Pascal. Входными данными является текст программы на языке C++, а выходными текст оттранслированной программы на языке Pascal.
Постановка задачи 3
Проектирование лексического анализатора 4
Реализация лексического анализатора 6
Проектирование синтаксического анализатора 10
Реализация синтаксического анализатора 12
Проектирование транслятора 16
Реализация транслятора 17
if ( isalpha(buf[forward]) )
forward++;
forward++;
}
int i=0;
for (;lexeme_begin <= forward; i++, lexeme_begin++ ) //Записываем в переменную lexeme нужный кусок буфера с найденной лексемой)
lexeme[i] = buf[lexeme_begin];
lexeme[i]
= '\0';
}
Данная функция ищет лексемы в соответствии с диаграммой описанной при проектировании.
Каждый язык программирования имеет грамматику, которая предписывает синтаксическую структуру корректных программ.
Грамматика:
start → main stmt_list eof
stmt_list → { stmts }
stmts → stmt ; stmts
stmt → if cmp stmt | stmts
| if cmp stmt | stmt_list else stmt | stmt_list
| do stmt | stmts while cmp
| while cmp stmt | stmt_list
| id = expr
| type id_list
| ε
Id_list → id, id_list
cmp → ( term relop term )
expr → term op expr_b
expr_b → op term expr_b | ε
term → ( expr ) | id | sym | num
type → char | int
id → letter ( letter | digit )*
sym →’letter’
num → digit ( digit )*
relop → < | <= | == | != | > | >=
Синтаксический анализатор получает последовательность токенов от лексического анализатора и проверяет может ли эта строка порождаться грамматикой исходного языка.
Т. к. в грамматике нет левой рекурсии ее можно проанализировать методом рекурсивного спуска. Для реализации метода рекурсивного спуска для каждого нетерминала имеется процедура проверяющая правильность построения последовательности токенов. Встреча очередного нетерминала во входном потоке означает вызов процедуры для этого нетерминала. Метод рекурсивного спуска неявным образом строит дерево разбора.
//-------------------------
void Syntax()
{
char TokenVal[33];
FirstToken();
Token = GetNextToken( TokenVal );
if ( Token != kw_main ) error( 2, lexeme_table->back->lineno
);
Token = GetNextToken( TokenVal );
if ( Token != lb ) error( 4, lexeme_table->back->lineno
);
Token = GetNextToken( TokenVal );
if ( Token != rb ) error( 6, lexeme_table->back->lineno
);
Token = GetNextToken( TokenVal );
if ( Token != lfb )
error( 3, lexeme_table->back->lineno );
stmt_list();
Token = GetNextToken( TokenVal );
if ( Token != end_file ) error( 18, lexeme_table->back->lineno );
}
//------------------------
void stmt_list()
{
stmt (false);
Token = GetNextToken( TokenVal );
while ( Token!=rfb ) {
stmt (true);
Token = GetNextToken( TokenVal );
}
}
//--------------------------
void stmt( bool read )
{
// Получить следующий токен если нужно.
if ( !read ) Token = GetNextToken( TokenVal
);
switch ( Token ) {
// if ( cmp ) (stmt | stmt_list) else (stmt | stmt_list).
case kw_if: cmp();
// id = expr;
case id:
// while (cmp) do ( stmt | stmt_list ).
case kw_while: cmp();
// do (stmt | stmt_list) while (cmp);
case kw_do: Token = GetNextToken( TokenVal );
case dc: break;
case rfb: lexeme_table = lexeme_table->back; break;//возвращаемся
к предыдущему токкену
case type: char id_type[5];
case end_file: error( 9, lexeme_table->back->lineno );
default: break;
}
}
//-----------------------
void var_list( char * id_type )
{
Token
= GetNextToken( TokenVal );
while ( Token != dc) {
if ( Token != id ) error( 13, lexeme_table->back->lineno );
if (! addIdTable ( id_type ) ) error( 14, lexeme_table->back->lineno );
Token = GetNextToken( TokenVal );
if ( Token != comma && Token != dc ) error( 15, lexeme_table->back->lineno );
if ( Token == comma ) Token = GetNextToken ( TokenVal );
}
}
//----------------------