/*
 * @(#)file      Parser.jjt
 * @(#)author    Sun Microsystems, Inc.
 *
 * Copyright 1997-2003 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 */

options {
  MULTI=true;
  STATIC=false;
  NODE_PREFIX= "JDM";
  NODE_PACKAGE="com.sun.jmx.snmp.IPAcl";
}


PARSER_BEGIN(Parser)

package com.sun.jmx.snmp.IPAcl;

import java.io.*;

public class Parser {
}

PARSER_END(Parser)


SKIP :
{
  " "
| "\t"
| "\n"
| "\r"
| <"--" (~["\n","\r"])* ("\n"|"\r"|"\r\n")>
| <"#" (~["\n","\r"])* ("\n"|"\r"|"\r\n")>

}



/* RESERVED WORDS AND LITERALS */

TOKEN : 
{
  <ACCESS: "access">
| <ACL: "acl">
| <ASSIGN: "=">
| <COMMUNITIES: "communities">
| <ENTERPRISE: "enterprise">
| <HOSTS: "hosts">
| <LBRACE: "{">
| <MANAGERS: "managers">
| <RANGE: "-">
| <RBRACE: "}">
| <RO: "read-only">
| <RW: "read-write">
| <TRAP: "trap">
| <INFORM: "inform">
| <TRAPCOMMUNITY: "trap-community">
| <INFORMCOMMUNITY: "inform-community">
| <TRAPNUM: "trap-num">
}



TOKEN : /* LITERALS */
{
  < INTEGER_LITERAL:
        <DECIMAL_LITERAL> (["l","L"])?
      | <HEX_LITERAL> (["l","L"])?
      | <OCTAL_LITERAL> (["l","L"])?
  >
|
  < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
|
  < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
|      
  < #OCTAL_LITERAL: "0" (["0"-"7"])* >
}

TOKEN : /* V6 LITERALS */
{ 
  < V6_ADDRESS: ((( ( (<H> ":")+ (":")?) | "::" ) (<H> ":")* (<H> | (<D> "." <D> "." <D> "." <D>))) | ("::")) | ( (<H> ":")+ ":") >
|
  <#H: (["0"-"9","a"-"f","A"-"F"])+ >
| 
  <#D: (["0"-"9"])+ >
}
 
TOKEN : /* IDENTIFIERS */
{
  < IDENTIFIER: ( (<DIGIT>|<LETTER>)+ (<SEPARATOR>|<LETTER>|<DIGIT>)* (<DIGIT>|<LETTER>)+ ) | (<DIGIT>|<LETTER>)+ >
|
  < #LETTER: ["a"-"z","A"-"Z"] >
|
  < #SEPARATOR: ["-", "_"] >
|
  < #DIGIT: ["0"-"9"] >
|
 <CSTRING: "\"" (~["\""])* "\"">
}

 

TOKEN: /* SEPARATOR */
{
  < COMMA: "," >
| < DOT: "." >
| < MARK: "!" >
| < MASK: "/">
}

// A file can contain several acl definitions
//
JDMSecurityDefs SecurityDefs()  : {}
{
  [AclBlock()]
  [TrapBlock()]
  [InformBlock()]
  <EOF>
  { return jjtThis;}
}

void AclBlock(): {}
{
"acl" "=" "{" (AclItem())+ "}"
}

void AclItem(): {}
{
"{" jjtThis.com= Communities() jjtThis.access= Access() Managers() "}"
}

JDMCommunities Communities(): {}
{
"communities" "=" Community() ( "," Community())*

{return jjtThis;}

}

void Community(): 
{
  Token t;
}
{
t=<IDENTIFIER> {jjtThis.communityString= t.image;}
}

JDMAccess Access(): {}
{
"access" "=" ( <RO> {jjtThis.access= RO;}
              |
               <RW> {jjtThis.access= RW;}
             )
{return jjtThis;}
}


void Managers() : { }
{
"managers" "=" Host() ( "," Host())*
}

void Host() : 
{
  Token t;
}
{
HostName()
|
LOOKAHEAD(<INTEGER_LITERAL> ( "." <INTEGER_LITERAL> )* "/" <INTEGER_LITERAL>)
NetMask()
|
LOOKAHEAD(<V6_ADDRESS> "/" <INTEGER_LITERAL>)
NetMaskV6()
|
LOOKAHEAD(<INTEGER_LITERAL> ".")
IpAddress()
|
IpV6Address()
|
IpMask()
}

void HostName():
{
  Token t;
}
{
  t=<IDENTIFIER> { jjtThis.name.append(t.image); }
(
"." t=<IDENTIFIER> 
  {jjtThis.name.append( "." + t.image); }
)*

}

void IpAddress():
{
Token t;
}
{

t= <INTEGER_LITERAL> 
  {jjtThis.address.append(t.image); }
(
"." t= <INTEGER_LITERAL> 
  {jjtThis.address.append( "." + t.image); }
)*

}

void IpV6Address():
{
Token t;
}
{

t= <V6_ADDRESS> 
  {jjtThis.address.append(t.image); }
}

void IpMask():
{
Token t;
}
{

t= <INTEGER_LITERAL> 
  {jjtThis.address.append(t.image); }
(
"!" t= <INTEGER_LITERAL> 
  {jjtThis.address.append( "." + t.image); }
)*
}

void NetMask():
{
Token t;
}
{

t= <INTEGER_LITERAL> 
  {jjtThis.address.append(t.image); }
(
"." t= <INTEGER_LITERAL> 
  {jjtThis.address.append( "." + t.image); }
)* "/" t= <INTEGER_LITERAL> {jjtThis.mask = t.image; }
}

void NetMaskV6():
{
Token t;
}
{

t= <V6_ADDRESS> 
  {jjtThis.address.append(t.image); }

"/" t= <INTEGER_LITERAL> {jjtThis.mask = t.image; }
}

void TrapBlock(): { }
{
"trap" "=" "{" (TrapItem())* "}"
}

void TrapItem(): { }
{
"{" jjtThis.comm= TrapCommunity() TrapInterestedHost() (Enterprise())* "}"
}

JDMTrapCommunity TrapCommunity(): 
{
  Token t;
}
{
"trap-community" "=" t=<IDENTIFIER> { jjtThis.community= t.image; return jjtThis; }
}

void TrapInterestedHost(): { }
{
"hosts" "=" HostTrap() ("," HostTrap())*
}

void HostTrap() : 
{
  Token t;
}
{
HostName()
|
IpAddress()
|
IpV6Address()
}

void Enterprise(): 
{
  Token t;
}
{
"{"
"enterprise" "="  t=<CSTRING> {jjtThis.enterprise= t.image;}

"trap-num" "=" TrapNum() ("," TrapNum())*

"}"
}

void TrapNum():
{
  Token t;
}
{
  t=<INTEGER_LITERAL> {jjtThis.low= Integer.parseInt(t.image);}
[
  "-" t=<INTEGER_LITERAL> {jjtThis.high= Integer.parseInt(t.image);}
]
}


void InformBlock(): { }
{
"inform" "=" "{" (InformItem())* "}"
}

void InformItem(): { }
{
"{" jjtThis.comm= InformCommunity() InformInterestedHost() "}"
}

JDMInformCommunity InformCommunity(): 
{
  Token t;
}
{
"inform-community" "=" t=<IDENTIFIER> { jjtThis.community= t.image; return jjtThis; }
}

void InformInterestedHost(): { }
{
"hosts" "=" HostInform() ("," HostInform())*
}

void HostInform() : 
{
  Token t;
}
{
HostName()
|
IpAddress()
|
IpV6Address()
}

