Home | History | Annotate | Download | only in parser
      1 /*@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 */
      2 /*@egen*//****************************************************************
      3  * Licensed to the Apache Software Foundation (ASF) under one   *
      4  * or more contributor license agreements.  See the NOTICE file *
      5  * distributed with this work for additional information        *
      6  * regarding copyright ownership.  The ASF licenses this file   *
      7  * to you under the Apache License, Version 2.0 (the            *
      8  * "License"); you may not use this file except in compliance   *
      9  * with the License.  You may obtain a copy of the License at   *
     10  *                                                              *
     11  *   http://www.apache.org/licenses/LICENSE-2.0                 *
     12  *                                                              *
     13  * Unless required by applicable law or agreed to in writing,   *
     14  * software distributed under the License is distributed on an  *
     15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
     16  * KIND, either express or implied.  See the License for the    *
     17  * specific language governing permissions and limitations      *
     18  * under the License.                                           *
     19  ****************************************************************/
     20 
     21 
     22 /**
     23  * RFC2822 address list parser.
     24  *
     25  * Created 9/17/2004
     26  * by Joe Cheng <code (at) joecheng.com>
     27  */
     28 
     29 options {
     30 	STATIC=false;
     31 	LOOKAHEAD=1;
     32 	//DEBUG_PARSER=true;
     33 	//DEBUG_TOKEN_MANAGER=true;
     34 }
     35 
     36 PARSER_BEGIN(AddressListParser)
     37 /*
     38  *  Copyright 2004 the mime4j project
     39  *
     40  *  Licensed under the Apache License, Version 2.0 (the "License");
     41  *  you may not use this file except in compliance with the License.
     42  *  You may obtain a copy of the License at
     43  *
     44  *      http://www.apache.org/licenses/LICENSE-2.0
     45  *
     46  *  Unless required by applicable law or agreed to in writing, software
     47  *  distributed under the License is distributed on an "AS IS" BASIS,
     48  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     49  *  See the License for the specific language governing permissions and
     50  *  limitations under the License.
     51  */
     52 package org.apache.james.mime4j.field.address.parser;
     53 
     54 public class AddressListParser/*@bgen(jjtree)*/implements AddressListParserTreeConstants/*@egen*/ {/*@bgen(jjtree)*/
     55   protected JJTAddressListParserState jjtree = new JJTAddressListParserState();
     56 
     57 /*@egen*/
     58     public static void main(String args[]) throws ParseException {
     59 		while (true) {
     60 		    try {
     61 				AddressListParser parser = new AddressListParser(System.in);
     62 		    	parser.parseLine();
     63 		    	((SimpleNode)parser.jjtree.rootNode()).dump("> ");
     64 		    } catch (Exception x) {
     65 				x.printStackTrace();
     66 				return;
     67 		    }
     68 		}
     69     }
     70 
     71     private static void log(String msg) {
     72     	System.out.print(msg);
     73     }
     74 
     75     public ASTaddress_list parse() throws ParseException {
     76         try {
     77     	    parseAll();
     78     	    return (ASTaddress_list)jjtree.rootNode();
     79     	} catch (TokenMgrError tme) {
     80     	    throw new ParseException(tme.getMessage());
     81     	}
     82     }
     83 
     84 
     85     void jjtreeOpenNodeScope(Node n) {
     86     	((SimpleNode)n).firstToken = getToken(1);
     87     }
     88 
     89     void jjtreeCloseNodeScope(Node n) {
     90     	((SimpleNode)n).lastToken = getToken(0);
     91     }
     92 }
     93 
     94 PARSER_END(AddressListParser)
     95 
     96 void parseLine()       :
     97 {}
     98 {
     99 	address_list() ["\r"] "\n"
    100 }
    101 
    102 void parseAll()       :
    103 {}
    104 {
    105 	address_list() <EOF>
    106 }
    107 
    108 void address_list() :
    109 {/*@bgen(jjtree) address_list */
    110   ASTaddress_list jjtn000 = new ASTaddress_list(JJTADDRESS_LIST);
    111   boolean jjtc000 = true;
    112   jjtree.openNodeScope(jjtn000);
    113   jjtreeOpenNodeScope(jjtn000);
    114 /*@egen*/}
    115 {/*@bgen(jjtree) address_list */
    116         try {
    117 /*@egen*/
    118 	[ address() ]
    119 	(
    120 		","
    121 		[ address() ]
    122 	)*/*@bgen(jjtree)*/
    123         } catch (Throwable jjte000) {
    124           if (jjtc000) {
    125             jjtree.clearNodeScope(jjtn000);
    126             jjtc000 = false;
    127           } else {
    128             jjtree.popNode();
    129           }
    130           if (jjte000 instanceof RuntimeException) {
    131             throw (RuntimeException)jjte000;
    132           }
    133           if (jjte000 instanceof ParseException) {
    134             throw (ParseException)jjte000;
    135           }
    136           throw (Error)jjte000;
    137         } finally {
    138           if (jjtc000) {
    139             jjtree.closeNodeScope(jjtn000, true);
    140             jjtreeCloseNodeScope(jjtn000);
    141           }
    142         }
    143 /*@egen*/
    144 }
    145 
    146 void address() :
    147 {/*@bgen(jjtree) address */
    148   ASTaddress jjtn000 = new ASTaddress(JJTADDRESS);
    149   boolean jjtc000 = true;
    150   jjtree.openNodeScope(jjtn000);
    151   jjtreeOpenNodeScope(jjtn000);
    152 /*@egen*/}
    153 {/*@bgen(jjtree) address */
    154         try {
    155 /*@egen*/
    156 	LOOKAHEAD(2147483647)
    157 	addr_spec()
    158 |	angle_addr()
    159 |	( phrase() (group_body() | angle_addr()) )/*@bgen(jjtree)*/
    160         } catch (Throwable jjte000) {
    161           if (jjtc000) {
    162             jjtree.clearNodeScope(jjtn000);
    163             jjtc000 = false;
    164           } else {
    165             jjtree.popNode();
    166           }
    167           if (jjte000 instanceof RuntimeException) {
    168             throw (RuntimeException)jjte000;
    169           }
    170           if (jjte000 instanceof ParseException) {
    171             throw (ParseException)jjte000;
    172           }
    173           throw (Error)jjte000;
    174         } finally {
    175           if (jjtc000) {
    176             jjtree.closeNodeScope(jjtn000, true);
    177             jjtreeCloseNodeScope(jjtn000);
    178           }
    179         }
    180 /*@egen*/
    181 }
    182 
    183 void mailbox() :
    184 {/*@bgen(jjtree) mailbox */
    185   ASTmailbox jjtn000 = new ASTmailbox(JJTMAILBOX);
    186   boolean jjtc000 = true;
    187   jjtree.openNodeScope(jjtn000);
    188   jjtreeOpenNodeScope(jjtn000);
    189 /*@egen*/}
    190 {/*@bgen(jjtree) mailbox */
    191         try {
    192 /*@egen*/
    193 	LOOKAHEAD(2147483647)
    194 	addr_spec()
    195 |	angle_addr()
    196 |	name_addr()/*@bgen(jjtree)*/
    197         } catch (Throwable jjte000) {
    198           if (jjtc000) {
    199             jjtree.clearNodeScope(jjtn000);
    200             jjtc000 = false;
    201           } else {
    202             jjtree.popNode();
    203           }
    204           if (jjte000 instanceof RuntimeException) {
    205             throw (RuntimeException)jjte000;
    206           }
    207           if (jjte000 instanceof ParseException) {
    208             throw (ParseException)jjte000;
    209           }
    210           throw (Error)jjte000;
    211         } finally {
    212           if (jjtc000) {
    213             jjtree.closeNodeScope(jjtn000, true);
    214             jjtreeCloseNodeScope(jjtn000);
    215           }
    216         }
    217 /*@egen*/
    218 }
    219 
    220 void name_addr() :
    221 {/*@bgen(jjtree) name_addr */
    222   ASTname_addr jjtn000 = new ASTname_addr(JJTNAME_ADDR);
    223   boolean jjtc000 = true;
    224   jjtree.openNodeScope(jjtn000);
    225   jjtreeOpenNodeScope(jjtn000);
    226 /*@egen*/}
    227 {/*@bgen(jjtree) name_addr */
    228         try {
    229 /*@egen*/
    230 	phrase() angle_addr()/*@bgen(jjtree)*/
    231         } catch (Throwable jjte000) {
    232           if (jjtc000) {
    233             jjtree.clearNodeScope(jjtn000);
    234             jjtc000 = false;
    235           } else {
    236             jjtree.popNode();
    237           }
    238           if (jjte000 instanceof RuntimeException) {
    239             throw (RuntimeException)jjte000;
    240           }
    241           if (jjte000 instanceof ParseException) {
    242             throw (ParseException)jjte000;
    243           }
    244           throw (Error)jjte000;
    245         } finally {
    246           if (jjtc000) {
    247             jjtree.closeNodeScope(jjtn000, true);
    248             jjtreeCloseNodeScope(jjtn000);
    249           }
    250         }
    251 /*@egen*/
    252 }
    253 
    254 void group_body() :
    255 {/*@bgen(jjtree) group_body */
    256   ASTgroup_body jjtn000 = new ASTgroup_body(JJTGROUP_BODY);
    257   boolean jjtc000 = true;
    258   jjtree.openNodeScope(jjtn000);
    259   jjtreeOpenNodeScope(jjtn000);
    260 /*@egen*/}
    261 {/*@bgen(jjtree) group_body */
    262         try {
    263 /*@egen*/
    264 	":"
    265 	[ mailbox() ]
    266 	(
    267 		","
    268 		[ mailbox() ]
    269 	)*
    270 	";"/*@bgen(jjtree)*/
    271         } catch (Throwable jjte000) {
    272           if (jjtc000) {
    273             jjtree.clearNodeScope(jjtn000);
    274             jjtc000 = false;
    275           } else {
    276             jjtree.popNode();
    277           }
    278           if (jjte000 instanceof RuntimeException) {
    279             throw (RuntimeException)jjte000;
    280           }
    281           if (jjte000 instanceof ParseException) {
    282             throw (ParseException)jjte000;
    283           }
    284           throw (Error)jjte000;
    285         } finally {
    286           if (jjtc000) {
    287             jjtree.closeNodeScope(jjtn000, true);
    288             jjtreeCloseNodeScope(jjtn000);
    289           }
    290         }
    291 /*@egen*/
    292 }
    293 
    294 void angle_addr() :
    295 {/*@bgen(jjtree) angle_addr */
    296   ASTangle_addr jjtn000 = new ASTangle_addr(JJTANGLE_ADDR);
    297   boolean jjtc000 = true;
    298   jjtree.openNodeScope(jjtn000);
    299   jjtreeOpenNodeScope(jjtn000);
    300 /*@egen*/}
    301 {/*@bgen(jjtree) angle_addr */
    302         try {
    303 /*@egen*/
    304 	"<" [ route() ] addr_spec() ">"/*@bgen(jjtree)*/
    305         } catch (Throwable jjte000) {
    306           if (jjtc000) {
    307             jjtree.clearNodeScope(jjtn000);
    308             jjtc000 = false;
    309           } else {
    310             jjtree.popNode();
    311           }
    312           if (jjte000 instanceof RuntimeException) {
    313             throw (RuntimeException)jjte000;
    314           }
    315           if (jjte000 instanceof ParseException) {
    316             throw (ParseException)jjte000;
    317           }
    318           throw (Error)jjte000;
    319         } finally {
    320           if (jjtc000) {
    321             jjtree.closeNodeScope(jjtn000, true);
    322             jjtreeCloseNodeScope(jjtn000);
    323           }
    324         }
    325 /*@egen*/
    326 }
    327 
    328 void route() :
    329 {/*@bgen(jjtree) route */
    330   ASTroute jjtn000 = new ASTroute(JJTROUTE);
    331   boolean jjtc000 = true;
    332   jjtree.openNodeScope(jjtn000);
    333   jjtreeOpenNodeScope(jjtn000);
    334 /*@egen*/}
    335 {/*@bgen(jjtree) route */
    336         try {
    337 /*@egen*/
    338 	"@" domain() ( (",")* "@" domain() )* ":"/*@bgen(jjtree)*/
    339         } catch (Throwable jjte000) {
    340           if (jjtc000) {
    341             jjtree.clearNodeScope(jjtn000);
    342             jjtc000 = false;
    343           } else {
    344             jjtree.popNode();
    345           }
    346           if (jjte000 instanceof RuntimeException) {
    347             throw (RuntimeException)jjte000;
    348           }
    349           if (jjte000 instanceof ParseException) {
    350             throw (ParseException)jjte000;
    351           }
    352           throw (Error)jjte000;
    353         } finally {
    354           if (jjtc000) {
    355             jjtree.closeNodeScope(jjtn000, true);
    356             jjtreeCloseNodeScope(jjtn000);
    357           }
    358         }
    359 /*@egen*/
    360 }
    361 
    362 void phrase() :
    363 {/*@bgen(jjtree) phrase */
    364   ASTphrase jjtn000 = new ASTphrase(JJTPHRASE);
    365   boolean jjtc000 = true;
    366   jjtree.openNodeScope(jjtn000);
    367   jjtreeOpenNodeScope(jjtn000);
    368 /*@egen*/}
    369 {/*@bgen(jjtree) phrase */
    370 try {
    371 /*@egen*/
    372 (	<DOTATOM>
    373 |	<QUOTEDSTRING>
    374 )+/*@bgen(jjtree)*/
    375 } finally {
    376   if (jjtc000) {
    377     jjtree.closeNodeScope(jjtn000, true);
    378     jjtreeCloseNodeScope(jjtn000);
    379   }
    380 }
    381 /*@egen*/
    382 }
    383 
    384 void addr_spec() :
    385 {/*@bgen(jjtree) addr_spec */
    386   ASTaddr_spec jjtn000 = new ASTaddr_spec(JJTADDR_SPEC);
    387   boolean jjtc000 = true;
    388   jjtree.openNodeScope(jjtn000);
    389   jjtreeOpenNodeScope(jjtn000);
    390 /*@egen*/}
    391 {/*@bgen(jjtree) addr_spec */
    392         try {
    393 /*@egen*/
    394 	( local_part() "@" domain() )/*@bgen(jjtree)*/
    395         } catch (Throwable jjte000) {
    396           if (jjtc000) {
    397             jjtree.clearNodeScope(jjtn000);
    398             jjtc000 = false;
    399           } else {
    400             jjtree.popNode();
    401           }
    402           if (jjte000 instanceof RuntimeException) {
    403             throw (RuntimeException)jjte000;
    404           }
    405           if (jjte000 instanceof ParseException) {
    406             throw (ParseException)jjte000;
    407           }
    408           throw (Error)jjte000;
    409         } finally {
    410           if (jjtc000) {
    411             jjtree.closeNodeScope(jjtn000, true);
    412             jjtreeCloseNodeScope(jjtn000);
    413           }
    414         }
    415 /*@egen*/
    416 }
    417 
    418 void local_part() :
    419 {/*@bgen(jjtree) local_part */
    420   ASTlocal_part jjtn000 = new ASTlocal_part(JJTLOCAL_PART);
    421   boolean jjtc000 = true;
    422   jjtree.openNodeScope(jjtn000);
    423   jjtreeOpenNodeScope(jjtn000);
    424 /*@egen*/ Token t; }
    425 {/*@bgen(jjtree) local_part */
    426         try {
    427 /*@egen*/
    428 	( t=<DOTATOM> | t=<QUOTEDSTRING> )
    429 	(	[t="."]
    430 		{
    431 			if (t.image.charAt(t.image.length() - 1) != '.' || t.kind == AddressListParserConstants.QUOTEDSTRING)
    432 				throw new ParseException("Words in local part must be separated by '.'");
    433 		}
    434 		(	t=<DOTATOM> | t=<QUOTEDSTRING> )
    435 	)*/*@bgen(jjtree)*/
    436         } finally {
    437           if (jjtc000) {
    438             jjtree.closeNodeScope(jjtn000, true);
    439             jjtreeCloseNodeScope(jjtn000);
    440           }
    441         }
    442 /*@egen*/
    443 }
    444 
    445 void domain() :
    446 {/*@bgen(jjtree) domain */
    447   ASTdomain jjtn000 = new ASTdomain(JJTDOMAIN);
    448   boolean jjtc000 = true;
    449   jjtree.openNodeScope(jjtn000);
    450   jjtreeOpenNodeScope(jjtn000);
    451 /*@egen*/ Token t; }
    452 {/*@bgen(jjtree) domain */
    453         try {
    454 /*@egen*/
    455 	(	t=<DOTATOM>
    456 		(	[t="."]
    457 			{
    458 				if (t.image.charAt(t.image.length() - 1) != '.')
    459 					throw new ParseException("Atoms in domain names must be separated by '.'");
    460 			}
    461 			t=<DOTATOM>
    462 		)*
    463 	)
    464 |	<DOMAINLITERAL>/*@bgen(jjtree)*/
    465         } finally {
    466           if (jjtc000) {
    467             jjtree.closeNodeScope(jjtn000, true);
    468             jjtreeCloseNodeScope(jjtn000);
    469           }
    470         }
    471 /*@egen*/
    472 }
    473 
    474 SPECIAL_TOKEN :
    475 {
    476  	< WS: ( [" ", "\t"] )+ >
    477 }
    478 
    479 TOKEN :
    480 {
    481 	< #ALPHA: ["a" - "z", "A" - "Z"] >
    482 |	< #DIGIT: ["0" - "9"] >
    483 |	< #ATEXT: ( <ALPHA> | <DIGIT>
    484 			  | "!" | "#" | "$" | "%"
    485 			  | "&" | "'" | "*" | "+"
    486 			  | "-" | "/" | "=" | "?"
    487 			  | "^" | "_" | "`" | "{"
    488 			  | "|" | "}" | "~"
    489 			  )>
    490 |	< DOTATOM: <ATEXT> ( <ATEXT> | "." )* >
    491 }
    492 
    493 TOKEN_MGR_DECLS :
    494 {
    495 	// Keeps track of how many levels of comment nesting
    496 	// we've encountered.  This is only used when the 2nd
    497 	// level is reached, for example ((this)), not (this).
    498 	// This is because the outermost level must be treated
    499 	// specially anyway, because the outermost ")" has a
    500 	// different token type than inner ")" instances.
    501 	static int commentNest;
    502 }
    503 
    504 MORE :
    505 {
    506 	// domain literal
    507 	"[" : INDOMAINLITERAL
    508 }
    509 
    510 <INDOMAINLITERAL>
    511 MORE :
    512 {
    513 	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
    514 |	< ~["[", "]", "\\"] >
    515 }
    516 
    517 <INDOMAINLITERAL>
    518 TOKEN :
    519 {
    520 	< DOMAINLITERAL: "]" > { matchedToken.image = image.toString(); }: DEFAULT
    521 }
    522 
    523 MORE :
    524 {
    525 	// starts a comment
    526 	"(" : INCOMMENT
    527 }
    528 
    529 <INCOMMENT>
    530 SKIP :
    531 {
    532 	// ends a comment
    533 	< COMMENT: ")" > : DEFAULT
    534 	// if this is ever changed to not be a SKIP, need
    535 	// to make sure matchedToken.token = token.toString()
    536 	// is called.
    537 }
    538 
    539 <INCOMMENT>
    540 MORE :
    541 {
    542 	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
    543 |	"(" { commentNest = 1; } : NESTED_COMMENT
    544 |	< <ANY>>
    545 }
    546 
    547 <NESTED_COMMENT>
    548 MORE :
    549 {
    550 	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
    551 |	"(" { ++commentNest; }
    552 |	")" { --commentNest; if (commentNest == 0) SwitchTo(INCOMMENT); }
    553 |	< <ANY>>
    554 }
    555 
    556 
    557 // QUOTED STRINGS
    558 
    559 MORE :
    560 {
    561 	"\"" { image.deleteCharAt(image.length() - 1); } : INQUOTEDSTRING
    562 }
    563 
    564 <INQUOTEDSTRING>
    565 MORE :
    566 {
    567 	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
    568 |	< (~["\"", "\\"])+ >
    569 }
    570 
    571 <INQUOTEDSTRING>
    572 TOKEN :
    573 {
    574 	< QUOTEDSTRING: "\"" > { matchedToken.image = image.substring(0, image.length() - 1); } : DEFAULT
    575 }
    576 
    577 // GLOBALS
    578 
    579 <*>
    580 TOKEN :
    581 {
    582 	< #QUOTEDPAIR: "\\" <ANY> >
    583 |	< #ANY: ~[] >
    584 }
    585 
    586 // ERROR!
    587 /*
    588 
    589 <*>
    590 TOKEN :
    591 {
    592 	< UNEXPECTED_CHAR: <ANY> >
    593 }
    594 
    595 */