Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
бАКАЛАВР_РАБОТА.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
2.13 Mб
Скачать

Файл 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();

}