/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This file is part of SimpleC. * * See the file "SimpleC-LICENSE" for Copyright information and * * the terms and conditions for copying, distribution and * * modification of SimpleC. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ package org.sablecc.simplec; import org.sablecc.simplec.analysis.*; import org.sablecc.simplec.node.*; import java.util.*; class Declarations extends Walker { Hashtable declarations = new Hashtable(1); LinkedList function_declarations = new LinkedList(); LinkedList function_definitions = new LinkedList(); LinkedList global_variables = new LinkedList(); Hashtable local_variables = new Hashtable(1); Hashtable parameters = new Hashtable(1); TreeMap find_fct_decl = new TreeMap(StringComparator.instance); TreeMap find_fct_def = new TreeMap(StringComparator.instance); private TreeMap find_glb_var = new TreeMap(StringComparator.instance); private Hashtable find_loc_var = new Hashtable(1); private Hashtable find_param = new Hashtable(1); private AFunctionDeclaration currentFunctionDeclaration; private AFunctionDefinition currentFunctionDefinition; private AIdentifierDirectFunctionDeclarator currentFunctionDeclarator; private PParameterDeclaration currentParameterDeclaration; private AVariableDeclaration currentVariableDeclaration; private PDeclarator currentDeclarator; Declarations(Start ast) { ast.apply(this); ast.apply(new Walker() { public void inAFunctionDefinition(AFunctionDefinition node) { currentFunctionDefinition = node; } public void outAFunctionDefinition(AFunctionDefinition node) { currentFunctionDefinition = null; currentFunctionDeclarator = null; } public void inAIdentifierDirectFunctionDeclarator(AIdentifierDirectFunctionDeclarator node) { if(currentFunctionDefinition != null) { currentFunctionDeclarator = node; } } public void caseTIdentifier(TIdentifier node) { if(currentFunctionDeclarator != null) { String text = node.getText(); Object declaration = ((Map) find_loc_var.get( currentFunctionDeclarator.getIdentifier())). get(text); declaration = (declaration != null) ? declaration : ((Map) find_param.get( currentFunctionDeclarator.getIdentifier())). get(text); declaration = (declaration != null) ? declaration : find_glb_var.get(text); declaration = (declaration != null) ? declaration : find_fct_def.get(text); declaration = (declaration != null) ? declaration : find_fct_decl.get(text); if(declaration != null) { declarations.put(node, declaration); } } } }); find_glb_var = null; find_loc_var = null; find_param = null; currentFunctionDeclaration = null; currentFunctionDefinition = null; currentFunctionDeclarator = null; currentParameterDeclaration = null; currentVariableDeclaration = null; currentDeclarator = null; } public void inAFunctionDeclaration(AFunctionDeclaration node) { currentFunctionDeclaration = node; } public void outAFunctionDeclaration(AFunctionDeclaration node) { currentFunctionDeclaration = null; } public void inAFunctionDefinition(AFunctionDefinition node) { currentFunctionDefinition = node; } public void outAFunctionDefinition(AFunctionDefinition node) { currentFunctionDefinition = null; currentFunctionDeclarator = null; } public void inAIdentifierDirectFunctionDeclarator(AIdentifierDirectFunctionDeclarator node) { if(currentFunctionDeclaration != null) { function_declarations.add(node.getIdentifier()); find_fct_decl.put( node.getIdentifier().getText(), node.getIdentifier()); } else if(currentFunctionDefinition != null) { currentFunctionDeclarator = node; local_variables.put( node.getIdentifier(), new LinkedList()); find_loc_var.put( node.getIdentifier(), new TreeMap(StringComparator.instance)); parameters.put( node.getIdentifier(), new LinkedList()); find_param.put( node.getIdentifier(), new TreeMap(StringComparator.instance)); function_definitions.add(node.getIdentifier()); find_fct_def.put( node.getIdentifier().getText(), node.getIdentifier()); } } public void caseAParameterList(AParameterList node) { /* We walk the parameter list only if we are in a function definition */ if(node.parent() == currentFunctionDeclarator) { super.caseAParameterList(node); } } public void inAParameterDeclaration(AParameterDeclaration node) { currentParameterDeclaration = node; } public void outAParameterDeclaration(AParameterDeclaration node) { currentParameterDeclaration = null; } public void inAVariableDeclaration(AVariableDeclaration node) { currentVariableDeclaration = node; } public void outAVariableDeclaration(AVariableDeclaration node) { currentVariableDeclaration = null; } public void inAPointerDeclarator(APointerDeclarator node) { currentDeclarator = node; } public void outAPointerDeclarator(APointerDeclarator node) { currentDeclarator = null; } public void inADirectDeclarator(ADirectDeclarator node) { currentDeclarator = node; } public void outADirectDeclarator(ADirectDeclarator node) { currentDeclarator = null; } public void inAIdentifierDirectDeclarator(AIdentifierDirectDeclarator node) { addVariableOrParameter(node.getIdentifier()); } public void inAIdentifierArrayDeclarator(AIdentifierArrayDeclarator node) { addVariableOrParameter(node.getIdentifier()); } private void addVariableOrParameter(TIdentifier identifier) { if(currentFunctionDeclarator != null) { if(currentVariableDeclaration != null) { ((LinkedList) local_variables.get( currentFunctionDeclarator.getIdentifier())).add( identifier); ((Map) find_loc_var.get( currentFunctionDeclarator.getIdentifier())).put( identifier.getText(), identifier); } else if(currentParameterDeclaration != null) { ((LinkedList) parameters.get( currentFunctionDeclarator.getIdentifier())).add( identifier); ((Map) find_param.get( currentFunctionDeclarator.getIdentifier())).put( identifier.getText(), identifier); } } else if(currentVariableDeclaration != null) { global_variables.add(identifier); find_glb_var.put( identifier.getText(), identifier); } } }