blob: 99a5e336bb7070cd1f92fbae5705b98482707fcb [file] [log] [blame]
/****************************************************************
* 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. *
****************************************************************/
/**
* RFC2045 Content-Type parser.
*
* Created 10/2/2004
* by Joe Cheng <code@joecheng.com>
*/
options {
STATIC=false;
LOOKAHEAD=1;
JDK_VERSION = "1.5";
OUTPUT_DIRECTORY = "../../../../../../../../../target/generated-sources/javacc";
//DEBUG_PARSER=true;
//DEBUG_TOKEN_MANAGER=true;
}
PARSER_BEGIN(ContentTypeParser)
/****************************************************************
* 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. *
****************************************************************/
package org.apache.james.mime4j.field.contenttype.parser;
import java.util.List;
import java.util.ArrayList;
public class ContentTypeParser {
private String type;
private String subtype;
private List<String> paramNames = new ArrayList<String>();
private List<String> paramValues = new ArrayList<String>();
public String getType() { return type; }
public String getSubType() { return subtype; }
public List<String> getParamNames() { return paramNames; }
public List<String> getParamValues() { return paramValues; }
public static void main(String args[]) throws ParseException {
while (true) {
try {
ContentTypeParser parser = new ContentTypeParser(System.in);
parser.parseLine();
} catch (Exception x) {
x.printStackTrace();
return;
}
}
}
}
PARSER_END(ContentTypeParser)
void parseLine() :
{}
{
parse() ["\r"] "\n"
}
void parseAll() :
{}
{
parse() <EOF>
}
void parse() :
{
Token type;
Token subtype;
}
{
type=<ATOKEN> "/" subtype=<ATOKEN>
{
this.type = type.image;
this.subtype = subtype.image;
}
( ";" (parameter())? )*
}
void parameter() :
{
Token attrib;
String val;
}
{
attrib=<ATOKEN> "=" val=value()
{
paramNames.add(attrib.image);
paramValues.add(val);
}
}
String value() :
{Token t;}
{
( t=<ATOKEN>
| t=<DIGITS>
| t=<QUOTEDSTRING>
)
{ return t.image; }
}
SPECIAL_TOKEN :
{
< WS: ( [" ", "\t"] )+ >
}
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 :
{
// 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
}
TOKEN :
{
< DIGITS: ( ["0"-"9"] )+ >
}
TOKEN :
{
< ATOKEN: ( ~[" ", "\t", "(", ")", "<", ">", "@", ",", ";", ":", "\\", "\"", "/", "[", "]", "?", "="] )+ >
}
// GLOBALS
<*>
TOKEN :
{
< #QUOTEDPAIR: "\\" <ANY> >
| < #ANY: ~[] >
}