
- •Выпускная квалификационная работа бакалавра
- •Задание на выпускную квалификационную работу бакалавра
- •План-график выполнения работы
- •Реферат
- •Введение
- •1 Языковые процессоры
- •1.1 Практическое применениеискусственных языков
- •1.2 Практический пример
- •1.3 Понятие и структура языкового процессора
- •2Обзор существующих систем и обоснование выбора инструментальных средств и класса грамматики
- •2.1 Обзор существующей символьной спецификации моделей гс в среде исма
- •2.1.1 Лексемы языка исма
- •2.1.2 Грамматика языка исма
- •2.1.3 Семантические действия в языковом процессоре исма
- •2.1.4 Заключение
- •2.2 Обоснование выбора инструментальных средств и класса грамматики
- •3 Постановка задачи исследования
- •3.1 Характеристика задачи исследования
- •3.2 Входная информация
- •3.3 Выходная информация
- •3.4 Архитектура среды исма с расширенным языком описания гс
- •4 Программно-математическое обеспечение
- •4.1Лексический анализатор
- •4.1.1 Функции лексического анализатора
- •4.1.2 Спецификация токенови входного алфавита символов
- •4.1.3 Распознавание токенов
- •4.1.4 Иерархия классов модуля
- •4.2 Синтаксический анализатор
- •4.2.1 Функции синтаксического анализатора
- •4.2.2 Спецификация грамматики
- •4.2.3 Метод разбора
- •4.2.4 Восстановление после ошибок
- •4.2.5 Иерархия классов модуля
- •4.3 Семантический анализ
- •4.3.1 Промежуточное представление программы
- •4.3.2 Грамматика с семантическими правилами
- •4.3.3 Модифицированныйметодразбора
- •4.3.4 Семантический анализ. Таблица символов
- •4.3.5 Семантический анализ. Проверка корректности типа
- •4.4 Генерация кода
- •4.5 Система сбора диагностических сообщений
- •5 Тестирование
- •5.1 Лексический анализатор
- •5.2 Синтаксическийанализатор
- •5.3 Семантический анализатор
- •Заключение
- •Список использованных источников
- •ПриложениеA Диагностические сообщения
- •Диагностические сообщения сканера
- •Диагностические сообщения парсера
- •Диагностические сообщения семантического анализатора
- •ПриложениеБ
- •Б.1.3 Установка системы
- •Б.2 Работа с системой б.2.1 Запуск системы и начало работы
- •Б.2.2Ввод программной модели
- •Б.2.3Трансляция модели и просмотр результата
- •Б.2.4Сохранение программной модели
- •Б.2.6Завершение работы с системой
- •Приложение в
- •Листинг программы
- •В.1 Модуль лексического анализатора
- •Файл abstractLexer.H
- •Файл lexer.H
- •Файл lexer.Cpp
- •В.2 Модуль синтаксического анализатора Файл abstractParser.H
- •Файлparser_ll1.H
- •Файл parser_ll1.Cpp
- •В.3 Модуль семантического анализатора Файл symbolTable.H
- •Файл SymbolTableFactory.H
- •Файл checker.H
- •В.4 Модулькодогенератора ФайлastVisitor.H
- •Файл astCodeGen.H
Файл parser_ll1.Cpp
#include "parser/parser_LL1.h"
// panic mode
...
inline void parser_LL1::Parser_LL1::error(Type_error type)
{
syntaxError=true;
static logger::Logger & diag=logger::Logger::getLogger();
string prefix="syntax error - "+lex->getLine()+": ";
switch(type){
case EXPECT_TERM:
diag.log(prefix+"expected token "+"\'"+Token::tagToString(parsStack.top())+"\'");
parsStack.pop();
break;
case INVAL_FIRST:
diag.log(prefix+"skiped token "+"\'"+look->toString()+"\'");
move();
if(look->tag== Token::END) throw System_error("critical error: infinite cycle");
break;
case EXPECT_NON_TERM:
diag.log(prefix+"expected non-terminal "+"\'"+Token::tagToString(parsStack.top())+"\'");
parsStack.pop();
break;
}
}
parser_LL1::Parser_LL1::Parser_LL1(lexer::AbstractLexer* l,AstBuilder* b )
:lex(l),lookahead_valid(false),builder(b)
{
init_table();
syntaxError=false;
parsStack.push(Token::END);
parsStack.push(Token::program);
move();
}
inline void parser_LL1::Parser_LL1::move()
{
if(lookahead_valid){
look=lookahead;
lookahead_valid=false;
} else
look= lex->scan();
}
inline void parser_LL1::Parser_LL1::compute_lookahead()
{
if(!lookahead_valid){
lookahead= lex->scan();
lookahead_valid=true;
}
}
parser_LL1::Node* parser_LL1::Parser_LL1::parsing()
{
Token::Tag currSymbol=Token::program;
shared_ptr<Token> lastToken;
// try{
while( currSymbol != Token::END){
if ( currSymbol < Token::program ){
if(currSymbol == look->tag){
parsStack.pop();
lastToken=look;
move();
}
else error(EXPECT_TERM);
}
else if( currSymbol < Token::make_program){
Table::const_iterator i=table.find(key(currSymbol,Gramma_symbol(look->tag)));
if(i != table.end())
switch(i->second){
case r1: // program -> declsDefins {make_seq_decl} classicPart {make_seq_cl_p} hybridPart {make_seq_hyb_p, make_program}
parsStack.pop();
parsStack.push(Token::make_program);
parsStack.push(Token::make_seq_hyb_p);
parsStack.push(Token::hybridPart);
parsStack.push(Token::make_seq_cl_p);
parsStack.push(Token::classicPart);
parsStack.push(Token::make_seq_decl);
parsStack.push(Token::declsDefins);
break;
case r2_1: // declsDefins -> declDefins1 declsDefins
parsStack.pop();
parsStack.push(Token::declsDefins);
parsStack.push(Token::declsDefins1);
break;
case r2_3:// lookahead ( r2_1 or r2_2)
compute_lookahead();
if(lookahead->tag == '\'' || lookahead->tag == '~'){// r2_2
parsStack.pop();
} else { // r2_1
parsStack.pop();
parsStack.push(Token::declsDefins);
parsStack.push(Token::declsDefins1);
}
break;
case r2_2:// declsDefins -> null
parsStack.pop();
break;
case r3_1:// declsDefins1 -> macro id {make_id} param = expr ; {make_decl_macro}
parsStack.pop();
parsStack.push(Token::make_decl_macro);
parsStack.push(Gramma_symbol(';'));
parsStack.push(Token::expr);
parsStack.push(Gramma_symbol('='));
parsStack.push(Token::param);
parsStack.push(Token::make_id);
parsStack.push(Token::ID);
parsStack.push(Token::MACRO);
break;
case r3_2:// declsDefins1 -> const id {make_id} = sign ; {make_decl_const}
parsStack.pop();
parsStack.push(Token::make_decl_const);
parsStack.push(Gramma_symbol(';'));
parsStack.push(Token::sign);
parsStack.push(Gramma_symbol('='));
parsStack.push(Token::make_id);
parsStack.push(Token::ID);
parsStack.push(Token::CONST);
break;
case r3_3:// declsDefins -> array id {make_id} [ num {make_const_int} ] ; {make_decl_array}
parsStack.pop();
parsStack.push(Token::make_decl_array);
parsStack.push(Gramma_symbol(';'));
parsStack.push(Gramma_symbol(']'));
parsStack.push(Token::make_const_int);
parsStack.push(Token::NUM);
parsStack.push(Gramma_symbol('['));
parsStack.push(Token::make_id);
parsStack.push(Token::ID);
parsStack.push(Token::ARRAY);
break;
case r3_4:// declsDefins -> count id {make_id} = [ list_inter {make_list_inter} ] ; {make_decl_count}
parsStack.pop();
parsStack.push(Token::make_decl_count);
parsStack.push(Gramma_symbol(';'));
parsStack.push(Gramma_symbol(']'));
parsStack.push(Token::make_list_inter);
parsStack.push(Token::list_inter);
parsStack.push(Gramma_symbol('['));
parsStack.push(Gramma_symbol('='));
parsStack.push(Token::make_id);
parsStack.push(Token::ID);
parsStack.push(Token::COUNT);
break;
case r3_5:// declsDefins -> id {make_id} index = sign ; {make_set_global}
parsStack.pop();
parsStack.push(Token::make_set_global);
parsStack.push(Gramma_symbol(';'));
parsStack.push(Token::sign);
parsStack.push(Gramma_symbol('='));
parsStack.push(Token::index);
parsStack.push(Token::make_id);
parsStack.push(Token::ID);
break;
case r4:// list_inter -> interval list_inter1
parsStack.pop();
parsStack.push(Token::list_inter1);
parsStack.push(Token::interval);
break;
case r5_1:// list_inter1 -> , interval list_inter1
parsStack.pop();
parsStack.push(Token::list_inter1);
parsStack.push(Token::interval);
parsStack.push(Gramma_symbol(','));
break;
case r5_2:// list_inter1 -> null
parsStack.pop();
break;
case r6:// interval -> num {make_const_int} - num {make_const_int, make_interval}
parsStack.pop();
parsStack.push(Token::make_interval);
parsStack.push(Token::make_const_int);
parsStack.push(Token::NUM);
parsStack.push(Gramma_symbol('-'));
parsStack.push(Token::make_const_int);
parsStack.push(Token::NUM);
break;
case r7_1:// param -> [ id {make_id} ]
parsStack.pop();
parsStack.push(Gramma_symbol(']'));
parsStack.push(Token::make_id);
parsStack.push(Token::ID);
parsStack.push(Gramma_symbol('['));
break;
case r7_2:// param -> null
parsStack.pop();
break;
case r8_1:// sign -> - sign {make_unary_minus}
parsStack.pop();
parsStack.push(Token::make_unary_minus);
parsStack.push(Token::sign);
parsStack.push(Gramma_symbol('-'));
break;
case r8_2:// sign -> literal
parsStack.pop();
parsStack.push(Token::literal);
break;
case r9_1:// index -> [ expr_i ] {make_access}
parsStack.pop();
parsStack.push(Token::make_access);
parsStack.push(Gramma_symbol(']'));
parsStack.push(Token::expr_i);
parsStack.push(Gramma_symbol('['));
break;
case r9_2:// index -> null
parsStack.pop();
break;
case r10_1:// classicPart -> classicPart1 classicPart
parsStack.pop();
parsStack.push(Token::classicPart);
parsStack.push(Token::classicPart1);
break;
case r10_3:// lookahead ( r10_1 or r10_2)
compute_lookahead();
if(lookahead->tag == '\'' || lookahead->tag == '~'){// r10_1
parsStack.pop();
parsStack.push(Token::classicPart);
parsStack.push(Token::classicPart1);
} else { // r10_2
parsStack.pop();
}
break;
case r10_2:// classicPart -> null
parsStack.pop();
break;
case r11_1:// classicPart1 -> equation
parsStack.pop();
parsStack.push(Token::equation);
break;
case r11_2:// classicPart1 -> condition
parsStack.pop();
parsStack.push(Token::condition);
break;
case r12:// condition -> if ( Bool ) then localValues {make_seq_loc_v} endif ; {make_if}
parsStack.pop();
parsStack.push(Token::make_if);
parsStack.push(Gramma_symbol(';'));
parsStack.push(Token::ENDIF);
parsStack.push(Token::make_seq_loc_v);
parsStack.push(Token::localValues);
parsStack.push(Token::THEN);
parsStack.push(Gramma_symbol(')'));
parsStack.push(Token::Bool);
parsStack.push(Gramma_symbol('('));
parsStack.push(Token::IF);
break;
case r13:// equation -> id {make_id} der {make_der} index = expr ; {make_equation}
parsStack.pop();
parsStack.push(Token::make_equation);
parsStack.push(Gramma_symbol(';'));
parsStack.push(Token::expr);
parsStack.push(Gramma_symbol('='));
parsStack.push(Token::index);
parsStack.push(Token::make_der);
parsStack.push(Token::der);
parsStack.push(Token::make_id);
parsStack.push(Token::ID);
break;
case r14:// localValues -> localValue localValues1
parsStack.pop();
parsStack.push(Token::localValues1);
parsStack.push(Token::localValue);
break;
case r15_1:// localValues1 -> localValue localValues1
parsStack.pop();
parsStack.push(Token::localValues1);
parsStack.push(Token::localValue);
break;
case r15_2:// localValues1 -> null
parsStack.pop();
break;
case r16:// localValue -> id {make_id} index = expr ; {make_set_local}
parsStack.pop();
parsStack.push(Token::make_set_local);
parsStack.push(Gramma_symbol(';'));
parsStack.push(Token::expr);
parsStack.push(Gramma_symbol('='));
parsStack.push(Token::index);
parsStack.push(Token::make_id);
parsStack.push(Token::ID);
break;
case r17_1:// der -> '
parsStack.pop();
parsStack.push(Gramma_symbol('\''));
break;
case r17_2:// der -> ~
parsStack.pop();
parsStack.push(Gramma_symbol('~'));
break;
case r18:// Bool -> join Bool1
parsStack.pop();
parsStack.push(Token::Bool1);
parsStack.push(Token::join);
break;
case r19_1:// Bool1 -> or join {make_or} Bool1
parsStack.pop();
parsStack.push(Token::Bool1);
parsStack.push(Token::make_or);
parsStack.push(Token::join);
parsStack.push(Token::OR);
break;
case r19_2:// Bool1 -> null
parsStack.pop();
break;
case r20:// join -> equality join1
parsStack.pop();
parsStack.push(Token::join1);
parsStack.push(Token::equality);
break;
case r21_1:// join1 -> and equality {make_and} join1
parsStack.pop();
parsStack.push(Token::join1);
parsStack.push(Token::make_and);
parsStack.push(Token::equality);
parsStack.push(Token::AND);
break;
case r21_2:// join1 -> null
parsStack.pop();
break;
case r22:// equality -> rel equality1
parsStack.pop();
parsStack.push(Token::equality1);
parsStack.push(Token::rel);
break;
case r23_1:// equality1 -> == rel {make_eq}
parsStack.pop();
parsStack.push(Token::make_eq);
parsStack.push(Token::rel);
parsStack.push(Token::EQ);
break;
case r23_2:// equality1 -> (!=|<>) rel {make_ne}
parsStack.pop();
parsStack.push(Token::make_ne);
parsStack.push(Token::rel);
parsStack.push(Token::NE);
break;
case r23_3:// equality1 -> null
parsStack.pop();
break;
case r24_1:// rel -> expr rel1
parsStack.pop();
parsStack.push(Token::rel1);
parsStack.push(Token::expr);
break;
case r25_1:// rel1 ->< expr { make_less }
parsStack.pop();
parsStack.push(Token::make_less);
parsStack.push(Token::expr);
parsStack.push(Gramma_symbol('<'));
break;
case r25_2:// rel1 ->> expr {make_gr}
parsStack.pop();
parsStack.push(Token::make_gr);
parsStack.push(Token::expr);
parsStack.push(Gramma_symbol('>'));
break;
case r25_3:// rel1 -><= expr {make_le}
parsStack.pop();
parsStack.push(Token::make_le);
parsStack.push(Token::expr);
parsStack.push(Token::LE);
break;
case r25_4:// rel1 ->>= expr {make_ge}
parsStack.pop();
parsStack.push(Token::make_ge);
parsStack.push(Token::expr);
parsStack.push(Token::GE);
break;
case r25_5:// rel1 -> null
parsStack.pop();
break;
case r27:// expr -> term expr1
parsStack.pop();
parsStack.push(Token::expr1);
parsStack.push(Token::term);
break;
case r28_1:// expr1 -> - term {make_sub} expr1
parsStack.pop();
parsStack.push(Token::expr1);
parsStack.push(Token::make_sub);
parsStack.push(Token::term);
parsStack.push(Gramma_symbol('-'));
break;
case r28_2:// expr1 -> + term {make_sum} expr1
parsStack.pop();
parsStack.push(Token::expr1);
parsStack.push(Token::make_sum);
parsStack.push(Token::term);
parsStack.push(Gramma_symbol('+'));
break;
case r28_3:// expr1 -> null
parsStack.pop();
break;
case r29:// term -> unary term1
parsStack.pop();
parsStack.push(Token::term1);
parsStack.push(Token::unary);
break;
case r30_1:// term1 -> / unary {make_div} term1
parsStack.pop();
parsStack.push(Token::term1);
parsStack.push(Token::make_div);
parsStack.push(Token::unary);
parsStack.push(Gramma_symbol('/'));
break;
case r30_2:// term1 -> * unary {make_mul} term1
parsStack.pop();
parsStack.push(Token::term1);
parsStack.push(Token::make_mul);
parsStack.push(Token::unary);
parsStack.push(Gramma_symbol('*'));
break;
case r30_3:// term1 -> null
parsStack.pop();
break;
case r31_1:// unary -> factor
parsStack.pop();
parsStack.push(Token::factor);
break;
case r31_2:// unary -> - unary {make_unary_minus}
parsStack.pop();
parsStack.push(Token::make_unary_minus);
parsStack.push(Token::unary);
parsStack.push(Gramma_symbol('-'));
break;
case r31_3:// unary -> not unary {make_unary_not}
parsStack.pop();
parsStack.push(Token::make_unary_not);
parsStack.push(Token::unary);
parsStack.push(Token::NOT);
break;
case r32_1:// factor -> ( Bool )
parsStack.pop();
parsStack.push(Gramma_symbol(')'));
parsStack.push(Token::Bool);
parsStack.push(Gramma_symbol('('));
break;
case r32_2:// factor -> id {make_id} spec
parsStack.pop();
parsStack.push(Token::spec);
parsStack.push(Token::make_id);
parsStack.push(Token::ID);
break;
case r32_3:// factor -> real {make_const_float}
parsStack.pop();
parsStack.push(Token::make_const_float);
parsStack.push(Token::REAL);
break;
case r32_4:// factor -> num {make_const_int}
parsStack.pop();
parsStack.push(Token::make_const_int);
parsStack.push(Token::NUM);
break;
case r33_1:// spec -> index
parsStack.pop();
parsStack.push(Token::index);
break;
case r33_2:// spec -> ( {make_start_list} list_expr ) {make_list_arg, make_func}
parsStack.pop();
parsStack.push(Token::make_func);
parsStack.push(Token::make_list_arg);
parsStack.push(Gramma_symbol(')'));
parsStack.push(Token::list_expr);
parsStack.push(Token::make_start_list);
parsStack.push(Gramma_symbol('('));
break;
case r34:// list_expr -> expr list_expr1
parsStack.pop();
parsStack.push(Token::list_expr1);
parsStack.push(Token::expr);
break;
case r35_1:// list_expr1 -> , expr list_expr1
parsStack.pop();
parsStack.push(Token::list_expr1);
parsStack.push(Token::expr);
parsStack.push(Gramma_symbol(','));
break;
case r35_2:// list_expr1 -> null
parsStack.pop();
break;
case r36_1: // hybridPart -> localState hybridPart
parsStack.pop();
parsStack.push(Token::hybridPart);
parsStack.push(Token::localState);
break;
case r36_2:// hybridPart -> null
parsStack.pop();
break;
case r37:// localState -> ver is body {make_seq_eq_locval} from list_ver {make_list_vers} ; {make_loc_state}
parsStack.pop();
parsStack.push(Token::make_loc_state);
parsStack.push(Gramma_symbol(';'));
parsStack.push(Token::make_list_vers);
parsStack.push(Token::list_ver);
parsStack.push(Token::FROM);
parsStack.push(Token::make_seq_eq_locval);
parsStack.push(Token::body);
parsStack.push(Token::IS);
parsStack.push(Token::ver);
break;
case r38:// ver -> id {make_id} cond
parsStack.pop();
parsStack.push(Token::cond);
parsStack.push(Token::make_id);
parsStack.push(Token::ID);
break;
case r39_1:// cond -> [ Bool ] {make_ver_cond}
parsStack.pop();
parsStack.push(Token::make_ver_cond);
parsStack.push(Gramma_symbol(']'));
parsStack.push(Token::Bool);
parsStack.push(Gramma_symbol('['));
break;
case r39_2:// cond -> null {make_ver}
parsStack.pop();
parsStack.push(Token::make_ver);
break;
case r40_1:// body -> body1 body
parsStack.pop();
parsStack.push(Token::body);
parsStack.push(Token::body1);
break;
case r40_2:// body -> null
parsStack.pop();
break;
case r41_3:// lookahead ( r41_1 or r41_2)
compute_lookahead();
if(lookahead->tag == '\'' || lookahead->tag == '~'){// r41_2 body1 -> equation
parsStack.pop();
parsStack.push(Token::equation);
} else { // r41_1 body1 -> localValue
parsStack.pop();
parsStack.push(Token::localValue);
}
break;
case r42_1:// list_ver -> ver list_ver1
parsStack.pop();
parsStack.push(Token::list_ver1);
parsStack.push(Token::ver);
break;
case r42_2:// list_ver -> null
parsStack.pop();
break;
case r43_1:// list_ver1 -> , ver list_ver1
parsStack.pop();
parsStack.push(Token::list_ver1);
parsStack.push(Token::ver);
parsStack.push(Gramma_symbol(','));
break;
case r43_2:// list_ver1 -> null
parsStack.pop();
break;
case r44_1:// literal -> num {make_const_int}
parsStack.pop();
parsStack.push(Token::make_const_int);
parsStack.push(Token::NUM);
break;
case r44_2:// literal -> real {make_const_float}
parsStack.pop();
parsStack.push(Token::make_const_float);
parsStack.push(Token::REAL);
break;
case r45:// expr_i -> term_i expr1_i
parsStack.pop();
parsStack.push(Token::expr1_i);
parsStack.push(Token::term_i);
break;
case r46_1:// expr1_i -> + term_i {make_sum} expr1_i
parsStack.pop();
parsStack.push(Token::expr1_i);
parsStack.push(Token::make_sum);
parsStack.push(Token::term_i);
parsStack.push(Gramma_symbol('+'));
break;
case r46_2:// expr1_i -> - term_i {make_sub} expr1_i
parsStack.pop();
parsStack.push(Token::expr1_i);
parsStack.push(Token::make_sub);
parsStack.push(Token::term_i);
parsStack.push(Gramma_symbol('-'));
break;
case r46_3:// expr1_i -> null
parsStack.pop();
break;
case r47:// term_i -> unary_i term1_i
parsStack.pop();
parsStack.push(Token::term1_i);
parsStack.push(Token::unary_i);
break;
case r48_1:// term1_i -> / unary_i term1_i
parsStack.pop();
parsStack.push(Token::term1_i);
parsStack.push(Token::make_div);
parsStack.push(Token::unary_i);
parsStack.push(Gramma_symbol('/'));
break;
case r48_2: // term1_i -> * unary_1 term1_i
parsStack.pop();
parsStack.push(Token::term1_i);
parsStack.push(Token::make_mul);
parsStack.push(Token::unary_i);
parsStack.push(Gramma_symbol('*'));
break;
case r48_3:// term1_i -> null
parsStack.pop();
break;
case r49_1:// unary_i -> factor_i
parsStack.pop();
parsStack.push(Token::factor_i);
break;
case r49_2:// unary_i -> - unary_i {make_unary_minus}
parsStack.pop();
parsStack.push(Token::make_unary_minus);
parsStack.push(Token::unary_i);
parsStack.push(Gramma_symbol('-'));
break;
case r50_1:// factor_i -> ( expr_i)
parsStack.pop();
parsStack.push(Gramma_symbol(')'));
parsStack.push(Token::expr_i);
parsStack.push(Gramma_symbol('('));
break;
case r50_2:// factor_i -> id {make_id}
parsStack.pop();
parsStack.push(Token::make_id);
parsStack.push(Token::ID);
break;
case r50_3:// factor_i -> num {make_const_int}
parsStack.pop();
parsStack.push(Token::make_const_int);
parsStack.push(Token::NUM);
break;
case SYNCH: // error synch
error(EXPECT_NON_TERM);
break;
default:
throw System_error("parser error: incorrect value of field!");
}
else { // default production is null-production
switch(currSymbol){
case Token::param:
case Token::sign:
case Token::index:
case Token::list_inter1:
case Token::localValues1:
case Token::Bool1:
case Token::join1:
case Token::equality1:
case Token::rel1:
case Token::expr1:
case Token::term1:
case Token::list_expr1:
case Token::cond:
case Token::body:
case Token::list_ver:
case Token::list_ver1:
case Token::expr1_i:
case Token::term1_i:
parsStack.pop();break;
default:
error(INVAL_FIRST);}// error
}
} else {
parsStack.pop();
if( !syntaxError){
switch(currSymbol){
case Token::make_program:
{
Seq* hybridPart=dynamic_cast<Seq*>(semanticStack.pop()) ;
Seq* classicPart=dynamic_cast<Seq*>(semanticStack.pop()) ;
Seq* declaration=dynamic_cast<Seq*>(semanticStack.pop()) ;;
semanticStack.push(new Program(lex->getLine(),declaration,classicPart,hybridPart));
}
break;
case Token::make_decl_macro:
{
Expr* body=dynamic_cast<Expr*>(semanticStack.pop()) ;
Id* param=0;
if(typeid(*semanticStack[semanticStack.size()-2])== typeid(Id)){
param=dynamic_cast<Id*>(semanticStack.pop()) ;
}
Id* id=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(new DeclMacro(lex->getLine(),id,param,body));
}
break;
case Token::make_decl_const:
{
Expr* value=dynamic_cast<Expr*>(semanticStack.pop()) ;
Id* id=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(new DeclConst(lex->getLine(),id,value));
}
break;
case Token::make_decl_array:
{
ConstantInt* dim=dynamic_cast<ConstantInt*>(semanticStack.pop()) ;
Id* id=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(new DeclArray(lex->getLine(),id,dim));
}
break;
case Token::make_decl_count:
{
ListExpr* intervals=dynamic_cast<ListExpr*>(semanticStack.pop()) ;
Id* id=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(new DeclCount(lex->getLine(),id,intervals));
}
break;
//-----------------------------------------------------------------------
case Token::make_seq_cl_p:
{
if ( semanticStack.empty() || (!TopIsClassicPart(semanticStack)))
semanticStack.push( new Seq() );
else
{
Seq* list = new Seq( lex->getLine(),dynamic_cast<Stmt*> (semanticStack.pop()),0 );
while ( ! semanticStack.empty() && TopIsClassicPart(semanticStack) )
list = new Seq( lex->getLine(),dynamic_cast<Stmt*> ( semanticStack.pop()), list );
semanticStack.push( list );
}
}
break;
case Token::make_seq_eq_locval:// body of LocalState
{
if ( semanticStack.empty() || (!TopIsEquatLocVal(semanticStack)))
semanticStack.push( new Seq() );
else
{
Seq* list = new Seq( lex->getLine(),dynamic_cast<Stmt*> (semanticStack.pop()),0 );
while ( ! semanticStack.empty() && TopIsEquatLocVal(semanticStack) )
list = new Seq( lex->getLine(),dynamic_cast<Stmt*> ( semanticStack.pop()), list );
semanticStack.push( list );
}
}
break;
case Token::make_seq_loc_v:
{
if ( semanticStack.empty() || (!TopIsLocalValues(semanticStack)))
semanticStack.push( new Seq() );
else
{
Seq* list = new Seq( lex->getLine(),dynamic_cast<Stmt*> (semanticStack.pop()),0 );
while ( ! semanticStack.empty() && TopIsLocalValues(semanticStack) )
list = new Seq( lex->getLine(),dynamic_cast<Stmt*> ( semanticStack.pop()), list );
semanticStack.push( list );
}
}
break;
case Token::make_seq_hyb_p:
{
if ( semanticStack.empty() || (!TopIsHybridPart(semanticStack)))
semanticStack.push( new Seq() );
else
{
Seq* list = new Seq( lex->getLine(),dynamic_cast<Stmt*> (semanticStack.pop()),0 );
while ( ! semanticStack.empty() && TopIsHybridPart(semanticStack) )
list = new Seq( lex->getLine(),dynamic_cast<Stmt*> ( semanticStack.pop()), list );
semanticStack.push( list );
}
}
break;
case Token::make_seq_decl:
{
if ( semanticStack.empty() || (!TopIsDeclarations(semanticStack)))
semanticStack.push( new Seq() );
else
{
Seq* list = new Seq( lex->getLine(),dynamic_cast<Stmt*> (semanticStack.pop()),0 );
while ( ! semanticStack.empty() && TopIsDeclarations(semanticStack) )
list = new Seq( lex->getLine(),dynamic_cast<Stmt*> ( semanticStack.pop()), list );
semanticStack.push( list );
}
}
break;
//---------------------------------------------------------------
case Token::make_set_global:
{
Expr* rvalue=dynamic_cast<Expr*>(semanticStack.pop()) ;
if(typeid(*semanticStack.top())== typeid(Id)){
Id* lvalue=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(new SetGlobal(lex->getLine(),lvalue,rvalue));
} else {
Access* lvalue= dynamic_cast<Access*>(semanticStack.pop()) ;
semanticStack.push(new SetGlobalIndex(lex->getLine(),lvalue,rvalue));
}
}
break;
case Token::make_equation:
{
Expr* expr=dynamic_cast<Expr*>(semanticStack.pop()) ;
if(typeid(*semanticStack.top())== typeid(Der)){
Der* d=dynamic_cast<Der*>(semanticStack.pop()) ;
Id* lvalue=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(new Equation(lex->getLine(),lvalue,d,expr));
} else {
Expr* index=dynamic_cast<Expr*>(semanticStack.pop()) ;
Der* d=dynamic_cast<Der*>(semanticStack.pop()) ;
Id* lvalue=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(new EquationIndex(lex->getLine(),builder->buildAccess(lex->getLine(),lvalue,index) ,d,expr));
}
}
break;
case Token::make_set_local:
{
Expr* expr=dynamic_cast<Expr*>(semanticStack.pop()) ;
if(typeid(*semanticStack.top())== typeid(Id)){
Id* lvalue=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(new SetLocal(lex->getLine(),lvalue,expr));
} else {
Access* lvalue= dynamic_cast<Access*>(semanticStack.pop()) ;
semanticStack.push(new SetLocalIndex(lex->getLine(),lvalue,expr));
}
}
break;
case Token::make_if:
{
Seq* localValues=dynamic_cast<Seq*>(semanticStack.pop()) ;
Expr* Bool=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(new If(lex->getLine(),Bool,localValues));
}
break;
case Token::make_loc_state:
{
ListExpr* vers=dynamic_cast<ListExpr*>(semanticStack.pop()) ;
Seq* body=dynamic_cast<Seq*>(semanticStack.pop()) ;
Ver* ver=dynamic_cast<Ver*>(semanticStack.pop()) ;
semanticStack.push(new LocalState(lex->getLine(),ver,body,vers));
}
break;
//--------------------------------------------------------------
case Token::make_list_inter:
{
ListExpr* list = builder->buildListExpr( lex->getLine(),dynamic_cast<Expr*> (semanticStack.pop()),0 );
while ( ! semanticStack.empty() && TopIsIntervals(semanticStack) )
list = builder->buildListExpr( lex->getLine(),dynamic_cast<Expr*> ( semanticStack.pop()), list );
semanticStack.push( list );
}
break;
case Token::make_start_list:
{
semanticStack.push( new ListExpr() );
}
break;
case Token::make_list_arg:
{
ListExpr* list = builder->buildListExpr(lex->getLine(),dynamic_cast<Expr*> (semanticStack.pop()),0);
while ( ! semanticStack.empty() && !TopIsListExpr(semanticStack) )
list = builder->buildListExpr(lex->getLine(),dynamic_cast<Expr*> (semanticStack.pop()),list );
delete semanticStack.pop(); // delete start list
semanticStack.push( list );
}
break;
case Token::make_list_vers:
{
if ( semanticStack.empty() || (!TopIsVers(semanticStack)))
semanticStack.push( new ListExpr() );
else
{
ListExpr* list = new ListExpr( lex->getLine(),dynamic_cast<Expr*> (semanticStack.pop()),0 );
while ( ! semanticStack.empty() && TopIsVers(semanticStack) )
list = new ListExpr( lex->getLine(),dynamic_cast<Expr*> ( semanticStack.pop()), list );
semanticStack.push( list );
}
}
break;
//------------------------------------------------------------------------------------------------
case Token::make_access:
{
if(typeid(*semanticStack[semanticStack.size()-2])== typeid(Id)){
Expr* index=dynamic_cast<Expr*>(semanticStack.pop()) ;
Id* array=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(builder->buildAccess(lex->getLine(),array,index));
}
}
break;
case Token::make_func:
{
ListExpr* args=dynamic_cast<ListExpr*>(semanticStack.pop()) ;
Id* func=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(builder->buildFunc(lex->getLine(),func,args));
}
break;
case Token::make_unary_minus:
{
Expr* x=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(builder->buildUnaryMinus(lex->getLine(),x));
}
break;
case Token::make_unary_not:
{
Expr* x=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(new UnaryNot(lex->getLine(),x));
}
break;
case Token::make_const_int:
{
semanticStack.push(builder->buildConstantInt(lex->getLine(),/*dynamic_cast<IntLiteral*> */ dynamic_pointer_cast<IntLiteral,Token>(lastToken)->value));
}
break;
case Token::make_const_float:
{
semanticStack.push(builder->buildConstantFloat(lex->getLine(),/*dynamic_cast<FloatLiteral*>*/ dynamic_pointer_cast<FloatLiteral,Token>(lastToken)->value));
}
break;
case Token::make_id:
{
semanticStack.push(builder->buildId(lex->getLine(),/*dynamic_cast<Word*>*/ dynamic_pointer_cast<Word,Token>(lastToken)->lexeme));
}
break;
case Token::make_der:
{
semanticStack.push(new Der(lex->getLine(),lastToken->toString()));
}
break;
case Token::make_interval:
{
ConstantInt* rhs=dynamic_cast<ConstantInt*>(semanticStack.pop()) ;
ConstantInt* lhs=dynamic_cast<ConstantInt*>(semanticStack.pop()) ;
semanticStack.push(new Interval(lex->getLine(),lhs->value(),rhs->value()));
}
break;
case Token::make_or:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(new Or(lex->getLine(),x1,x2));
}
break;
case Token::make_and:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(new And(lex->getLine(),x1,x2));
}
break;
case Token::make_eq:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(new Eq(lex->getLine(),x1,x2));
}
break;
case Token::make_ne:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(new Ne(lex->getLine(),x1,x2));
}
break;
case Token::make_less:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(new Less(lex->getLine(),x1,x2));
}
break;
case Token::make_gr:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(new Gr(lex->getLine(),x1,x2));
}
break;
case Token::make_le:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(new Le(lex->getLine(),x1,x2));
}
break;
case Token::make_ge:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(new Ge(lex->getLine(),x1,x2));
}
break;
case Token::make_sub:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(builder->buildMinusExp(lex->getLine(),x1,x2));
}
break;
case Token::make_sum:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(builder->buildPlusExp(lex->getLine(),x1,x2));
}
break;
case Token::make_div:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(builder->buildDivExp(lex->getLine(),x1,x2));
}
break;
case Token::make_mul:
{
Expr* x2=dynamic_cast<Expr*>(semanticStack.pop()) ;
Expr* x1=dynamic_cast<Expr*>(semanticStack.pop()) ;
semanticStack.push(builder->buildMulExp(lex->getLine(),x1,x2));
}
break;
case Token::make_ver:
{
Id* id=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(new Ver(lex->getLine(),id,0));
}
break;
case Token::make_ver_cond:
{
Expr* Bool=dynamic_cast<Expr*>(semanticStack.pop()) ;
Id* id=dynamic_cast<Id*>(semanticStack.pop()) ;
semanticStack.push(new Ver(lex->getLine(),id,Bool));
}
break;
default:
throw System_error("parser error: incorrect semantic marker!");
}
}
}
currSymbol=parsStack.top();
}
return semanticStack.pop();
}
…