Автор: Пользователь скрыл имя, 26 Февраля 2011 в 14:37, курсовая работа
Задачей данного курсового проекта является написание транслятора из языка высокого уровня С++ в язык Pascal. Входными данными является текст программы на языке C++, а выходными текст оттранслированной программы на языке Pascal.
Постановка задачи 3
Проектирование лексического анализатора 4
Реализация лексического анализатора 6
Проектирование синтаксического анализатора 10
Реализация синтаксического анализатора 12
Проектирование транслятора 16
Реализация транслятора 17
void cmp()
{
// Проверка открывающейся скобки.
Token = GetNextToken( TokenVal );
if
( Token != lb ) error( 4, lexeme_table->back->lineno );
//Проверка первого терма
Token = GetNextToken( TokenVal );
if
(Token != id && Token != num && Token != sym) error(
20, lexeme_table->back->lineno );
// Проверка знака неравенства.
Token = GetNextToken( TokenVal );
if
(Token != relop ) error( 5, lexeme_table->back->lineno );
//Проверка второго терма
Token = GetNextToken( TokenVal );
if
( Token != id && Token != num && Token != sym)
error( 20, lexeme_table->back->lineno );
// Проверка закрывающейся скобки.
Token = GetNextToken( TokenVal );
if
( Token != rb ) error( 6, lexeme_table->back->lineno );
}
//----------------------------
// Продукция expr.(a+b)
void expr()
{
term();
expr_b();
}
// Продукция term.
void term()
{
Token
= GetNextToken( TokenVal );
switch ( Token ) {
case lb: expr();
case num: break;
case id: break;
case sym: break;
default: error( 8, lexeme_table->back->lineno );
}
}
// Продукция expr_b.
void expr_b()
{
Token = GetNextToken( TokenVal );
if ( Token != dc && Token != rb )
if ( Token == op ) expr();
else error( 8, lexeme_table->back->lineno );
}
Здесь для каждой продукции пишется одноименная функция, которая вызывается в момент предположительного ее появления. Эти функции вызываются рекурсивно, отсюда и название – метод рекурсивного спуска.
После лексического и синтаксического анализа идет процесс трансляции программы. Каждому токену из исходного языка противопоставлен токен из целевого языка в соответствии с управляющей таблицей. Т.е. например токену “{” на языке C++ противопоставлен токен “begin” на языке Pascal. Так противопоставляя токенам исходного языка С++, токены целевого языка Pascal мы получим оттранслированный код.
void Translate ()
{
/*-------------------ЗАПИСЬ
ОБЪЯВЛЕННЫХ ПЕРЕМЕННЫХ В
ID_TABLE *first;
bool FirstRec = false;
// Запись переменных в файл.
if ( IdTable != NULL ) {
first = IdTable;
out<<"VAR"<<endl;
// Переменный типа char.
do {
if ( IdTable->type == char_type ) {
if ( FirstRec ) out<<",";
out<<
FirstR
}
IdTable = IdTable->Next;
} while ( IdTable != NULL );
if
( FirstRec ) out<<":char;\n";
FirstRec = false;
IdTable = first;
// Переменных типа int.
do {
if ( IdTable->type == int_type ) {
if ( FirstRec ) out<<",";
out<<
FirstR
}
IdTable = IdTable->Next;
} while ( IdTable != NULL );
if ( FirstRec ) out<<":integer;\n";
}
/* ----------------------- Трансляция основной программы. --------------------- */
FirstToken();
Token = GetNextToken( TokenVal );
Token = GetNextToken( TokenVal );
Token = GetNextToken( TokenVal );
Token = GetNextToken( TokenVal );
while ( Token != end_file ) {
// Пропустить объявление переменных.
if ( Token == type ) {
while ( GetNextToken( TokenVal )!=dc );
Token = GetNextToken( TokenVal );
continue;
}
// Запись слова then после if.
else if ( Token == kw_if ) {
for (int i=0; i<6; i++ ) {
Transl
Token = GetNextToken( TokenVal );
}
out<<"then"<
}
// Получение оттранслированного токена.
TranslateToken( Token, TokenVal);
// Получение следующего токена.
Token = GetNextToken( TokenVal );
};
out<<"."<<endl;
out.close();
}
/*----------------------------
void TranslateToken (TOKEN token, char *attribute)
{
switch ( token ) {
case id: out<<attribute; break;
case op: out<<attribute; break;
case num: out<<attribute; break;
case sym: out<<attribute; break;
case dc: out<<";\n"; break;
case lfb: out<<"begin\n"; break;
case rfb: out<<"end\n"; break;
case lb: out<<"("; break;
case rb: out<<")"; break;
case app: out<<":="; break;
case kw_if: out<<"if"; break;
case
kw_else: out<<"else\n"; break
case kw_do: out<<"repeat\n";break;
case kw_while: if ( !strcmp( attribute,"DO" ) ) out<<"until";
case relop: if ( !strcmp( attribute,"!=" ) ) out<<"<>" ;
}
}
Из-за
специфики языка Pascal все переменные должны
быть объявлены до начала программы. Для
этого они все во время синтаксического
анализа были записаны в отдельный список,
а на этапе трансляции сначала выводятся
они. В основном же цикле трансляции мы
пропускаем все объявления переменных.