// Parse a declaration. // // declaration: // [specifier-seq] basic-declaration // // basic-declaration: // variable-declaration // function-declaration // type-declaration // concept-declaration Decl& Parser::declaration() { // Parse and cache the specifier sequences. specifier_seq(); switch (lookahead()) { case tk::var_tok: return variable_declaration(); case tk::def_tok: return function_declaration(); case tk::class_tok: return class_declaration(); case tk::concept_tok: lingo_unreachable(); case tk::super_tok: return super_declaration(); default: break; } throw Syntax_error("invalid declaration"); }
virtual void postorder(Context ctx, AST_t node) { DeclaredEntity function_declaration(node, ctx.scope_link); AugmentedSymbol symbol = function_declaration.get_declared_symbol(); if (symbol.is_task()) { _table.insert(symbol); } }
void global_declaration() { // global_declaration ::= enum_decl | variable_decl | function_decl // // enum_decl ::= 'enum' [id] '{' id ['=' 'num'] {',' id ['=' 'num'} '}' // // variable_decl ::= type {'*'} id { ',' {'*'} id } ';' // // function_decl ::= type {'*'} id '(' parameter_decl ')' '{' body_decl '}' int type; // tmp, actual type for variable int i; // tmp basetype = INT; // parse enum, this should be treated alone. if (token == Enum) { // enum [id] { a = 10, b = 20, ... } match(Enum); if (token != '{') { match(Id); // skip the [id] part } if (token == '{') { // parse the assign part match('{'); enum_declaration(); match('}'); } match(';'); return; } // parse type information if (token == Int) { match(Int); } else if (token == Char) { match(Char); basetype = CHAR; } // parse the comma seperated variable declaration. while (token != ';' && token != '}') { type = basetype; // parse pointer type, note that there may exist `int ****x;` while (token == Mul) { match(Mul); type = type + PTR; } if (token != Id) { // invalid declaration printf("%d: bad global declaration\n", line); exit(-1); } if (current_id[Class]) { // identifier exists printf("%d: duplicate global declaration\n", line); exit(-1); } match(Id); current_id[Type] = type; if (token == '(') { current_id[Class] = Fun; current_id[Value] = (int)(text + 1); // the memory address of function function_declaration(); } else { // variable declaration current_id[Class] = Glo; // global variable current_id[Value] = (int)data; // assign memory address data = data + sizeof(int); } if (token == ',') { match(','); } } next(); }
virtual void postorder(Context ctx, AST_t node) { DeclaredEntity function_declaration(node, ctx.scope_link); AugmentedSymbol symbol = function_declaration.get_declared_symbol(); _table.insert( FunctionTable::table_t::value_type(symbol.get_qualified_name(), symbol) ); }
void global_declaration() { int type; int i; basetype = Int; if (token == Enum) { match(Enum); if (token == Id) { match(Id); } if (token == '{') { match('{'); enum_declaration(); match('}'); } match(';'); return; } if (token == Int) { match(Int); } else if (token == Char) { match(Char); basetype = Char; } while (token != ';' && token != '}') { type = basetype; while (token == Mul) { match(Mul); type = type + PTR; } if (token != Id) { printf("%d: bad global declaration\n", line); exit(-1); } if (current_id[Class]) { printf("%d: duplicate global declaration\n", line); exit(-1); } match(Id); current_id[Type] = type; if (token == '(') { current_id[Class] = Fun; current_id[Value] = (int)(text + 1); function_declaration(); } else { current_id[Class] = Glo; current_id[Value] = (int)data; data = data + sizeof(int); } if (token == ','){ match(','); } } next(); }