Yes. You can return a list of identifiers from ident_list like this:
List<String> ident_list() : {
List<String> ids = new ArrayList<String>() ;
String id ; }
{
id = identifier() { ids.add(id) ; }
(<COMMA> id = identifier() { ids.add(id) ; } )*
{return ids ; }
}
Now refactor var_decl a bit. What you do with the map is up to you, but I would stash it in in a node.
void var_decl() #var_decl : {
HashMap<String, String> decls = new HashMap<String, String>() ;
}
{
<VAR> one_var_decl(decls)
( <COMMA> one_var_decl(decls) )* <SEMIC>
{ jjThis.decls = decls ; }
}
And build the map in the new nonterminal.
void one_var_decl(HashMap<String, String> decls) #void :
{
List<String> ids ;
String ty ;
}
{
ids = ident_list() <COLON> ty = type()
{ for( String id <- ids ) {
// You may want to emit an error or warning here if there is a duplication.
decls.add(id, ty) ; } }
}