blob: c14277bc6019ce24ccae4fa95fccc1cf5b88c315 [file] [log] [blame]
/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. /Users/jason/Projects/apache-mime4j-0.3/target/generated-sources/jjtree/org/apache/james/mime4j/field/address/parser/AddressListParser.jj */
/*@egen*//****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
/**
* RFC2822 address list parser.
*
* Created 9/17/2004
* by Joe Cheng <code@joecheng.com>
*/
options {
STATIC=false;
LOOKAHEAD=1;
//DEBUG_PARSER=true;
//DEBUG_TOKEN_MANAGER=true;
}
PARSER_BEGIN(AddressListParser)
/*
* Copyright 2004 the mime4j project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.james.mime4j.field.address.parser;
public class AddressListParser/*@bgen(jjtree)*/implements AddressListParserTreeConstants/*@egen*/ {/*@bgen(jjtree)*/
protected JJTAddressListParserState jjtree = new JJTAddressListParserState();
/*@egen*/
public static void main(String args[]) throws ParseException {
while (true) {
try {
AddressListParser parser = new AddressListParser(System.in);
parser.parseLine();
((SimpleNode)parser.jjtree.rootNode()).dump("> ");
} catch (Exception x) {
x.printStackTrace();
return;
}
}
}
private static void log(String msg) {
System.out.print(msg);
}
public ASTaddress_list parse() throws ParseException {
try {
parseAll();
return (ASTaddress_list)jjtree.rootNode();
} catch (TokenMgrError tme) {
throw new ParseException(tme.getMessage());
}
}
void jjtreeOpenNodeScope(Node n) {
((SimpleNode)n).firstToken = getToken(1);
}
void jjtreeCloseNodeScope(Node n) {
((SimpleNode)n).lastToken = getToken(0);
}
}
PARSER_END(AddressListParser)
void parseLine() :
{}
{
address_list() ["\r"] "\n"
}
void parseAll() :
{}
{
address_list() <EOF>
}
void address_list() :
{/*@bgen(jjtree) address_list */
ASTaddress_list jjtn000 = new ASTaddress_list(JJTADDRESS_LIST);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
jjtreeOpenNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) address_list */
try {
/*@egen*/
[ address() ]
(
","
[ address() ]
)*/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
jjtreeCloseNodeScope(jjtn000);
}
}
/*@egen*/
}
void address() :
{/*@bgen(jjtree) address */
ASTaddress jjtn000 = new ASTaddress(JJTADDRESS);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
jjtreeOpenNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) address */
try {
/*@egen*/
LOOKAHEAD(2147483647)
addr_spec()
| angle_addr()
| ( phrase() (group_body() | angle_addr()) )/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
jjtreeCloseNodeScope(jjtn000);
}
}
/*@egen*/
}
void mailbox() :
{/*@bgen(jjtree) mailbox */
ASTmailbox jjtn000 = new ASTmailbox(JJTMAILBOX);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
jjtreeOpenNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) mailbox */
try {
/*@egen*/
LOOKAHEAD(2147483647)
addr_spec()
| angle_addr()
| name_addr()/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
jjtreeCloseNodeScope(jjtn000);
}
}
/*@egen*/
}
void name_addr() :
{/*@bgen(jjtree) name_addr */
ASTname_addr jjtn000 = new ASTname_addr(JJTNAME_ADDR);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
jjtreeOpenNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) name_addr */
try {
/*@egen*/
phrase() angle_addr()/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
jjtreeCloseNodeScope(jjtn000);
}
}
/*@egen*/
}
void group_body() :
{/*@bgen(jjtree) group_body */
ASTgroup_body jjtn000 = new ASTgroup_body(JJTGROUP_BODY);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
jjtreeOpenNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) group_body */
try {
/*@egen*/
":"
[ mailbox() ]
(
","
[ mailbox() ]
)*
";"/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
jjtreeCloseNodeScope(jjtn000);
}
}
/*@egen*/
}
void angle_addr() :
{/*@bgen(jjtree) angle_addr */
ASTangle_addr jjtn000 = new ASTangle_addr(JJTANGLE_ADDR);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
jjtreeOpenNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) angle_addr */
try {
/*@egen*/
"<" [ route() ] addr_spec() ">"/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
jjtreeCloseNodeScope(jjtn000);
}
}
/*@egen*/
}
void route() :
{/*@bgen(jjtree) route */
ASTroute jjtn000 = new ASTroute(JJTROUTE);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
jjtreeOpenNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) route */
try {
/*@egen*/
"@" domain() ( (",")* "@" domain() )* ":"/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
jjtreeCloseNodeScope(jjtn000);
}
}
/*@egen*/
}
void phrase() :
{/*@bgen(jjtree) phrase */
ASTphrase jjtn000 = new ASTphrase(JJTPHRASE);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
jjtreeOpenNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) phrase */
try {
/*@egen*/
( <DOTATOM>
| <QUOTEDSTRING>
)+/*@bgen(jjtree)*/
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
jjtreeCloseNodeScope(jjtn000);
}
}
/*@egen*/
}
void addr_spec() :
{/*@bgen(jjtree) addr_spec */
ASTaddr_spec jjtn000 = new ASTaddr_spec(JJTADDR_SPEC);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
jjtreeOpenNodeScope(jjtn000);
/*@egen*/}
{/*@bgen(jjtree) addr_spec */
try {
/*@egen*/
( local_part() "@" domain() )/*@bgen(jjtree)*/
} catch (Throwable jjte000) {
if (jjtc000) {
jjtree.clearNodeScope(jjtn000);
jjtc000 = false;
} else {
jjtree.popNode();
}
if (jjte000 instanceof RuntimeException) {
throw (RuntimeException)jjte000;
}
if (jjte000 instanceof ParseException) {
throw (ParseException)jjte000;
}
throw (Error)jjte000;
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
jjtreeCloseNodeScope(jjtn000);
}
}
/*@egen*/
}
void local_part() :
{/*@bgen(jjtree) local_part */
ASTlocal_part jjtn000 = new ASTlocal_part(JJTLOCAL_PART);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
jjtreeOpenNodeScope(jjtn000);
/*@egen*/ Token t; }
{/*@bgen(jjtree) local_part */
try {
/*@egen*/
( t=<DOTATOM> | t=<QUOTEDSTRING> )
( [t="."]
{
if (t.image.charAt(t.image.length() - 1) != '.' || t.kind == AddressListParserConstants.QUOTEDSTRING)
throw new ParseException("Words in local part must be separated by '.'");
}
( t=<DOTATOM> | t=<QUOTEDSTRING> )
)*/*@bgen(jjtree)*/
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
jjtreeCloseNodeScope(jjtn000);
}
}
/*@egen*/
}
void domain() :
{/*@bgen(jjtree) domain */
ASTdomain jjtn000 = new ASTdomain(JJTDOMAIN);
boolean jjtc000 = true;
jjtree.openNodeScope(jjtn000);
jjtreeOpenNodeScope(jjtn000);
/*@egen*/ Token t; }
{/*@bgen(jjtree) domain */
try {
/*@egen*/
( t=<DOTATOM>
( [t="."]
{
if (t.image.charAt(t.image.length() - 1) != '.')
throw new ParseException("Atoms in domain names must be separated by '.'");
}
t=<DOTATOM>
)*
)
| <DOMAINLITERAL>/*@bgen(jjtree)*/
} finally {
if (jjtc000) {
jjtree.closeNodeScope(jjtn000, true);
jjtreeCloseNodeScope(jjtn000);
}
}
/*@egen*/
}
SPECIAL_TOKEN :
{
< WS: ( [" ", "\t"] )+ >
}
TOKEN :
{
< #ALPHA: ["a" - "z", "A" - "Z"] >
| < #DIGIT: ["0" - "9"] >
| < #ATEXT: ( <ALPHA> | <DIGIT>
| "!" | "#" | "$" | "%"
| "&" | "'" | "*" | "+"
| "-" | "/" | "=" | "?"
| "^" | "_" | "`" | "{"
| "|" | "}" | "~"
)>
| < DOTATOM: <ATEXT> ( <ATEXT> | "." )* >
}
TOKEN_MGR_DECLS :
{
// Keeps track of how many levels of comment nesting
// we've encountered. This is only used when the 2nd
// level is reached, for example ((this)), not (this).
// This is because the outermost level must be treated
// specially anyway, because the outermost ")" has a
// different token type than inner ")" instances.
static int commentNest;
}
MORE :
{
// domain literal
"[" : INDOMAINLITERAL
}
<INDOMAINLITERAL>
MORE :
{
< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
| < ~["[", "]", "\\"] >
}
<INDOMAINLITERAL>
TOKEN :
{
< DOMAINLITERAL: "]" > { matchedToken.image = image.toString(); }: DEFAULT
}
MORE :
{
// starts a comment
"(" : INCOMMENT
}
<INCOMMENT>
SKIP :
{
// ends a comment
< COMMENT: ")" > : DEFAULT
// if this is ever changed to not be a SKIP, need
// to make sure matchedToken.token = token.toString()
// is called.
}
<INCOMMENT>
MORE :
{
< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
| "(" { commentNest = 1; } : NESTED_COMMENT
| < <ANY>>
}
<NESTED_COMMENT>
MORE :
{
< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
| "(" { ++commentNest; }
| ")" { --commentNest; if (commentNest == 0) SwitchTo(INCOMMENT); }
| < <ANY>>
}
// QUOTED STRINGS
MORE :
{
"\"" { image.deleteCharAt(image.length() - 1); } : INQUOTEDSTRING
}
<INQUOTEDSTRING>
MORE :
{
< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
| < (~["\"", "\\"])+ >
}
<INQUOTEDSTRING>
TOKEN :
{
< QUOTEDSTRING: "\"" > { matchedToken.image = image.substring(0, image.length() - 1); } : DEFAULT
}
// GLOBALS
<*>
TOKEN :
{
< #QUOTEDPAIR: "\\" <ANY> >
| < #ANY: ~[] >
}
// ERROR!
/*
<*>
TOKEN :
{
< UNEXPECTED_CHAR: <ANY> >
}
*/