You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdevelop/languages/ada/ada.store.g

611 lines
17 KiB

/* $Id$
* ANTLR Ada tree walker for building the Kdevelop class store
* Copyright (C) 2003 Oliver Kellogg <okellogg@users.sourceforge.net>
*/
header "pre_include_hpp" {
#include <qstring.h>
#include <qstringlist.h>
#include <qfileinfo.h>
#include <codemodel.h>
#include "AdaAST.hpp"
#include "ada_utils.hpp"
}
header "post_include_hpp" {
#include <codemodel.h>
#include <kdebug.h>
}
options {
language="Cpp";
}
class AdaStoreWalker extends AdaTreeParserSuper;
options {
importVocab = Ada;
ASTLabelType = "RefAdaAST";
}
{
private:
QString m_fileName;
QValueList<NamespaceDom> m_scopeStack;
CodeModel* m_model;
QValueList<QStringList> m_imports;
NamespaceDom m_currentContainer;
int m_currentAccess;
bool m_addToStore; /* auxiliary variable: for the moment, this is `true'
only when we are in specs, not bodies. */
bool m_isSubprogram; // auxiliary to def_id()
FileDom m_file;
public:
void setCodeModel (CodeModel* model) { m_model = model; }
CodeModel* codeModel () { return m_model; }
const CodeModel* codeModel () const { return m_model; }
QString fileName () const { return m_fileName; }
void setFileName (const QString& fileName) { m_fileName = fileName; }
void init () {
m_scopeStack.clear ();
m_imports.clear ();
m_currentContainer = m_model->globalNamespace ();
m_scopeStack.append (m_currentContainer);
m_currentAccess = CodeModelItem::Public;
m_addToStore = false;
m_isSubprogram = false;
if (m_model->hasFile(m_fileName))
m_model->removeFile (m_model->fileByName(m_fileName));
m_file = m_model->create<FileModel>();
m_file->setName(m_fileName);
m_model->addFile(m_file);
}
void wipeout () { m_model->wipeout (); }
// void out () { m_store->out (); }
void removeWithReferences (const QString& fileName) {
m_model->removeFile (m_model->fileByName(fileName));
}
NamespaceDom insertScopeContainer
(NamespaceDom scope, const QStringList & scopes ) {
QStringList::ConstIterator it = scopes.begin();
QString prefix( *it );
NamespaceDom ns = scope->namespaceByName( prefix );
// kdDebug() << "insertScopeContainer begin with prefix " << prefix << endl;
if (!ns.data()) {
// kdDebug() << "insertScopeContainer: ns is empty" << endl;
ns = m_model->create<NamespaceModel>();
// kdDebug() << "insertScopeContainer: ns created" << endl;
ns->setName( prefix );
// kdDebug() << "insertScopeContainer: ns name set" << endl;
scope->addNamespace( ns );
// kdDebug() << "insertScopeContainer: ns added to a scope" << endl;
if (scope == m_model->globalNamespace())
m_file->addNamespace( ns );
}
// kdDebug() << "insertScopeContainer: while" << endl;
while ( ++it != scopes.end() ) {
QString nameSegment( *it );
prefix += "." + nameSegment;
// kdDebug() << "insertScopeContainer: while prefix = " << prefix << endl;
NamespaceDom inner = scope->namespaceByName( prefix );
if (!inner.data() ) {
// kdDebug() << "insertScopeContainer: inner is empty " << endl;
inner = m_model->create<NamespaceModel>();
// kdDebug() << "insertScopeContainer: inner created " << endl;
inner->setName( nameSegment );
ns->addNamespace( inner );
// kdDebug() << "insertScopeContainer: inner added " << endl;
}
ns = inner;
}
return ns;
}
NamespaceDom defineScope( RefAdaAST namenode ) {
QStringList scopes( qnamelist( namenode ) );
// kdDebug() << "defineScope: " << scopes.join(" ") << endl;
NamespaceDom psc = insertScopeContainer( m_currentContainer, scopes );
// kdDebug() << "defineScope psc created" << endl;
psc->setStartPosition(namenode->getLine(), namenode->getColumn());
// kdDebug() << "defineScope start position set" << endl;
psc->setFileName(m_fileName);
// kdDebug() << "defineScope file name set" << endl;
// psc->setEndPosition (endLine, 0);
// kdDebug() << "defineScope return" << endl;
return psc;
}
}
/*
* Only those rules that require specific action for the tdevelop
* class store are overloaded here.
*/
compilation_unit
: { init(); }
context_items_opt ( library_item | subunit ) ( pragma )*
;
with_clause
: #(WITH_CLAUSE ( compound_name
// TBD: slurp in the actual files
)+ )
;
/*
compound_name
: IDENTIFIER
| #(DOT compound_name IDENTIFIER)
;
*/
use_clause
: #(USE_TYPE_CLAUSE ( subtype_mark )+ )
| #(USE_CLAUSE ( c:compound_name
{ m_imports.back ().push_back (qtext (#c)); }
)+ )
;
library_item :
#(LIBRARY_ITEM
#(MODIFIERS ( PRIVATE { m_currentAccess = CodeModelItem::Protected; } )? )
( lib_subprog_decl_or_rename_or_inst_or_body
| #(PACKAGE_BODY pb:def_id pkg_body_part)
| #(GENERIC_PACKAGE_INSTANTIATION gpi:def_id
{
defineScope( #gpi );
}
generic_inst
)
| #(PACKAGE_SPECIFICATION ps:def_id
{
NamespaceDom psc = defineScope( #ps );
m_currentContainer = psc;
m_scopeStack.append( psc );
m_addToStore = true;
}
pkg_spec_part
{
m_scopeStack.remove(m_scopeStack.last());
if (m_scopeStack.count() == 0) {
kdDebug() << "adastore: m_scopeStack is empty!" << endl;
m_scopeStack.append( m_model->globalNamespace() );
}
m_currentContainer = m_scopeStack.last();
// m_currentContainer->setEndPosition (endLine, 0);
m_addToStore = false;
}
)
| #(PACKAGE_RENAMING_DECLARATION prd:def_id
{
defineScope( #prd );
}
renames
)
| generic_decl
)
)
;
subprog_def_id
: { m_isSubprogram = true; }
def_id
{ m_isSubprogram = false; }
;
subprog_decl
: #(GENERIC_PROCEDURE_INSTANTIATION subprog_def_id generic_inst)
| #(PROCEDURE_RENAMING_DECLARATION subprog_def_id formal_part_opt renames)
| #(PROCEDURE_DECLARATION subprog_def_id formal_part_opt)
| #(PROCEDURE_BODY_STUB subprog_def_id formal_part_opt)
| #(ABSTRACT_PROCEDURE_DECLARATION subprog_def_id formal_part_opt)
| #(GENERIC_FUNCTION_INSTANTIATION def_designator generic_inst)
| #(FUNCTION_RENAMING_DECLARATION def_designator function_tail renames)
| #(FUNCTION_DECLARATION def_designator function_tail)
| #(FUNCTION_BODY_STUB def_designator function_tail)
| #(ABSTRACT_FUNCTION_DECLARATION subprog_def_id function_tail)
;
def_id
: cn:compound_name
{
// kdDebug() << "cn:compound_name started " << endl;
if (m_addToStore) {
// kdDebug() << "cn:compound_name m_addToStore " << endl;
if (m_isSubprogram) {
// kdDebug() << "cn:compound_name m_isSubprogram " << endl;
FunctionDom method = m_model->create<FunctionModel>();
method->setName (qtext (cn));
method->setFileName(m_fileName);
// kdDebug() << "cn:compound_name method->setStartPosition(" << endl;
method->setStartPosition(#cn->getLine(), #cn->getColumn());
if (m_currentContainer == m_model->globalNamespace())
m_file->addFunction(method);
else
m_currentContainer->addFunction(method);
//FIXME: adymo: is this valid for CodeModel
/* ParsedMethod *old = m_currentContainer->getMethod (method);
if (old) {
delete (method);
method = old;
} else {
m_currentContainer->addMethod (method);
}*/
} else {
// TBC: what about other declarations?
}
}
}
;
/*
generic_inst : compound_name ( value_s )?
;
*/
/*
formal_part_opt : #(FORMAL_PART_OPT ( parameter_specification )* )
;
*/
/*
parameter_specification
: #(PARAMETER_SPECIFICATION defining_identifier_list modifiers
subtype_mark init_opt)
;
*/
/*
defining_identifier_list : #(DEFINING_IDENTIFIER_LIST ( IDENTIFIER )+ )
;
*/
/*
renames : CHARACTER_STRING // CHARACTER_STRING should not really be there.
| OPERATOR_SYMBOL // OPERATOR_SYMBOL should be used instead.
| name
;
*/
/*
name : IDENTIFIER
| #(DOT name
( ALL
| IDENTIFIER
| CHARACTER_LITERAL
| OPERATOR_SYMBOL
)
)
| #(INDEXED_COMPONENT name value_s)
| #(TIC name attribute_id)
;
*/
def_designator
: cn:compound_name
{
// kdDebug() << "def_designator cn:compound_name started" << endl;
if (m_addToStore) {
// kdDebug() << "def_designator cn:compound_name m_addToStore" << endl;
FunctionDom method = m_model->create<FunctionModel>();
method->setName (qtext (cn));
method->setFileName(m_fileName);
// kdDebug() << "def_designator cn:compound_name method->setStartPosition(" << endl;
method->setStartPosition(#cn->getLine(), #cn->getColumn());
if (m_currentContainer == m_model->globalNamespace())
m_file->addFunction(method);
else
m_currentContainer->addFunction(method);
//FIXME: adymo: is this valid for CodeModel
/* ParsedMethod *old = m_currentContainer->getMethod (method);
if (old) {
delete method;
method = old;
} else {
m_currentContainer->addMethod (method);
}*/
}
}
| definable_operator_symbol
;
/*
function_tail : formal_part_opt subtype_mark
;
*/
spec_decl_part
: #(GENERIC_PACKAGE_INSTANTIATION def_id generic_inst)
| #(PACKAGE_SPECIFICATION ps:def_id
{
NamespaceDom psc = defineScope( #ps );
m_currentContainer = psc;
m_scopeStack.append( psc );
m_addToStore = true;
}
pkg_spec_part
{
m_scopeStack.remove(m_scopeStack.last());
if (m_scopeStack.count() == 0) {
kdDebug() << "adastore: m_scopeStack is empty!" << endl;
m_scopeStack.append( m_model->globalNamespace() );
}
m_currentContainer = m_scopeStack.last();
// m_currentContainer->setDeclarationEndsOnLine (endLine);
m_addToStore = false;
}
)
| #(PACKAGE_RENAMING_DECLARATION def_id renames)
;
pkg_spec_part :
basic_declarative_items_opt
private_declarative_items_opt
end_id_opt
;
private_declarative_items_opt
: ( { m_currentAccess = CodeModelItem::Protected; }
( basic_decl_item | pragma )+
{ m_currentAccess = CodeModelItem::Public; }
)?
;
/*
task_type_or_single_decl
: #(TASK_TYPE_DECLARATION def_id discrim_part_opt task_definition_opt)
| #(SINGLE_TASK_DECLARATION def_id task_definition_opt)
;
*/
/*
discriminant_specification
: #(DISCRIMINANT_SPECIFICATION defining_identifier_list
modifiers subtype_mark init_opt)
;
*/
/*
entry_declaration
: #(ENTRY_DECLARATION IDENTIFIER
discrete_subtype_def_opt formal_part_opt)
;
*/
/*
prot_op_decl
: entry_declaration
| #(PROCEDURE_DECLARATION def_id formal_part_opt)
| #(FUNCTION_DECLARATION def_designator function_tail)
| rep_spec
| pragma
;
*/
/*
prot_member_decl_s
: #(PROT_MEMBER_DECLARATIONS ( prot_op_decl | comp_decl )* )
;
comp_decl
: #(COMPONENT_DECLARATION defining_identifier_list component_subtype_def init_opt)
;
*/
/*
// decl_common is shared between declarative_item and basic_decl_item.
// decl_common only contains specifications.
decl_common
: // type_def:
#(ENUMERATION_TYPE_DECLARATION IDENTIFIER enum_id_s)
| #(SIGNED_INTEGER_TYPE_DECLARATION IDENTIFIER range)
| #(MODULAR_TYPE_DECLARATION IDENTIFIER expression)
| #(FLOATING_POINT_DECLARATION IDENTIFIER expression range_constraint_opt)
| #(ORDINARY_FIXED_POINT_DECLARATION IDENTIFIER expression range)
| #(DECIMAL_FIXED_POINT_DECLARATION IDENTIFIER expression expression range_constraint_opt)
| array_type_declaration
| access_type_declaration
//
| #(INCOMPLETE_TYPE_DECLARATION IDENTIFIER discrim_part_opt)
// derived_or_private_or_record
| #(PRIVATE_EXTENSION_DECLARATION id_and_discrim modifiers subtype_ind)
| #(DERIVED_RECORD_EXTENSION id_and_discrim modifiers subtype_ind record_definition)
| #(ORDINARY_DERIVED_TYPE_DECLARATION id_and_discrim subtype_ind)
| #(PRIVATE_TYPE_DECLARATION id_and_discrim modifiers)
| #(RECORD_TYPE_DECLARATION id_and_discrim modifiers record_definition)
//
| #(SUBTYPE_DECLARATION IDENTIFIER subtype_ind)
| generic_decl
| use_clause
| rep_spec // enumeration_representation_clause only
| #(EXCEPTION_RENAMING_DECLARATION def_id compound_name)
| #(OBJECT_RENAMING_DECLARATION def_id subtype_mark name)
| #(EXCEPTION_DECLARATION defining_identifier_list)
| #(NUMBER_DECLARATION defining_identifier_list expression)
| #(ARRAY_OBJECT_DECLARATION defining_identifier_list modifiers
array_type_definition init_opt)
| #(OBJECT_DECLARATION defining_identifier_list modifiers
subtype_ind init_opt)
;
*/
/*
id_and_discrim
: IDENTIFIER discrim_part_opt
;
*/
/*
enumeration_literal_specification : IDENTIFIER | CHARACTER_LITERAL
;
*/
/*
array_type_declaration
: #(ARRAY_TYPE_DECLARATION IDENTIFIER array_type_definition)
;
*/
/*
access_type_declaration
: #(ACCESS_TO_PROCEDURE_DECLARATION IDENTIFIER modifiers formal_part_opt)
| #(ACCESS_TO_FUNCTION_DECLARATION IDENTIFIER modifiers function_tail)
| #(ACCESS_TO_OBJECT_DECLARATION IDENTIFIER modifiers subtype_ind)
;
*/
generic_decl
: #(GENERIC_PACKAGE_RENAMING generic_formal_part_opt def_id renames)
| #(GENERIC_PACKAGE_DECLARATION generic_formal_part_opt gpd:def_id
{
NamespaceDom psc = defineScope( #gpd );
m_currentContainer = psc;
m_scopeStack.append( psc );
m_addToStore = true;
}
pkg_spec_part
{
m_scopeStack.remove(m_scopeStack.last());
if (m_scopeStack.count() == 0)
m_scopeStack.append( m_model->globalNamespace() );
m_currentContainer = m_scopeStack.last();
// m_currentContainer->setDeclarationEndsOnLine (endLine);
m_addToStore = false;
}
)
| #(GENERIC_PROCEDURE_RENAMING generic_formal_part_opt def_id
formal_part_opt renames)
| #(GENERIC_PROCEDURE_DECLARATION generic_formal_part_opt subprog_def_id
formal_part_opt)
| #(GENERIC_FUNCTION_RENAMING generic_formal_part_opt def_designator
function_tail renames)
| #(GENERIC_FUNCTION_DECLARATION generic_formal_part_opt subprog_def_id
function_tail)
;
/*
generic_formal_part_opt
: #(GENERIC_FORMAL_PART
( pragma | use_clause | generic_formal_parameter )*
)
;
*/
/*
generic_formal_parameter
: // FORMAL_TYPE_DECLARATIONs:
#(FORMAL_DISCRETE_TYPE_DECLARATION def_id)
| #(FORMAL_SIGNED_INTEGER_TYPE_DECLARATION def_id)
| #(FORMAL_MODULAR_TYPE_DECLARATION def_id)
| #(FORMAL_DECIMAL_FIXED_POINT_DECLARATION def_id)
| #(FORMAL_ORDINARY_FIXED_POINT_DECLARATION def_id)
| #(FORMAL_FLOATING_POINT_DECLARATION def_id)
| formal_array_type_declaration
| formal_access_type_declaration
| #(FORMAL_PRIVATE_TYPE_DECLARATION id_part modifiers)
| #(FORMAL_ORDINARY_DERIVED_TYPE_DECLARATION id_part subtype_ind)
| #(FORMAL_PRIVATE_EXTENSION_DECLARATION id_part modifiers subtype_ind)
| #(FORMAL_PROCEDURE_DECLARATION def_id formal_part_opt
subprogram_default_opt)
| #(FORMAL_FUNCTION_DECLARATION def_designator function_tail
subprogram_default_opt)
| #(FORMAL_PACKAGE_DECLARATION def_id compound_name formal_package_actual_part_opt)
| parameter_specification
;
*/
lib_subprog_decl_or_rename_or_inst_or_body
: { m_addToStore = true; }
( subprog_decl
| procedure_body
| function_body
)
{ m_addToStore = false; }
;
subprog_decl_or_rename_or_inst_or_body
: subprog_decl
| procedure_body
| function_body
;
/*
// A declarative_item may appear in the declarative part of any body.
declarative_item
: #(PACKAGE_BODY_STUB def_id)
| #(PACKAGE_BODY def_id pkg_body_part)
| spec_decl_part
| #(TASK_BODY_STUB def_id)
| #(TASK_BODY def_id body_part)
| task_type_or_single_decl
| #(PROTECTED_BODY_STUB def_id)
| #(PROTECTED_BODY def_id prot_op_bodies_opt)
| prot_type_or_single_decl
| subprog_decl_or_rename_or_inst_or_body
| decl_common
;
*/
subprog_decl_or_body
: procedure_body
| #(PROCEDURE_DECLARATION subprog_def_id formal_part_opt)
| function_body
| #(FUNCTION_DECLARATION def_designator function_tail)
;
/*
// Temporary, to be turned into just `qualified'.
// We get away with it because `qualified' is always mentioned
// together with `name'.
// Only exception: `code_stmt', which is not yet implemented.
name_or_qualified
: IDENTIFIER
| #(DOT name_or_qualified
( ALL
| IDENTIFIER
| CHARACTER_LITERAL
| OPERATOR_SYMBOL
)
)
| #(INDEXED_COMPONENT name_or_qualified value_s)
| #(TIC name_or_qualified
( parenthesized_primary
| attribute_id
)
)
;
*/
package_body
: #(PACKAGE_BODY id:def_id
/* TBD
{ QString name (qtext (id));
}
*/
pkg_body_part)
;
/*
task_body : #(TASK_BODY def_id body_part)
;
*/
/*
protected_body : #(PROTECTED_BODY def_id prot_op_bodies_opt)
;
*/