
/*
 * Copyright © 2002 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * California 95054, U.S.A. All rights reserved.  Sun Microsystems, Inc. has
 * intellectual property rights relating to technology embodied in the product
 * that is described in this document. In particular, and without limitation,
 * these intellectual property rights may include one or more of the U.S.
 * patents listed at http://www.sun.com/patents and one or more additional
 * patents or pending patent applications in the U.S. and in other countries.
 * U.S. Government Rights - Commercial software. Government users are subject
 * to the Sun Microsystems, Inc. standard license agreement and applicable
 * provisions of the FAR and its supplements.  Use is subject to license terms.
 * Sun,  Sun Microsystems,  the Sun logo and  Java are trademarks or registered
 * trademarks of Sun Microsystems, Inc. in the U.S. and other countries.  This
 * product is covered and controlled by U.S. Export Control laws and may be
 * subject to the export or import laws in other countries.  Nuclear, missile,
 * chemical biological weapons or nuclear maritime end uses or end users,
 * whether direct or indirect, are strictly prohibited.  Export or reexport
 * to countries subject to U.S. embargo or to entities identified on U.S.
 * export exclusion lists, including, but not limited to, the denied persons
 * and specially designated nationals lists is strictly prohibited.
 */


PARSER_BEGIN(Faq)

import java.io.*;

public class Faq {

  static int count = 0;

  static int beginAt = 1;

  static PrintWriter indstr;

  static {
    try {
      indstr = new PrintWriter(new FileWriter("index.html"));
      indstr.println("<title>Selected list of emails from the JavaCC mailing list</title>");
      indstr.println("<h2>Selected list of emails from the JavaCC mailing list</h2>");
    } catch (IOException e) {
      throw new Error();
    }
  }

  static String fix(String s) {
    String retval = "";
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      if (c == '<') {
        retval += "&lt;";
      } else if (c == '>') {
        retval += "&gt;";
      } else {
        retval += c;
      }
    }
    return retval;
  }

  public static void main(String args[]) throws ParseException {
    if (args.length == 1) {
      beginAt = Integer.parseInt(args[0]);
    }
    Faq parser = new Faq(System.in);
    parser.MailFile();
  }

}

PARSER_END(Faq)


// PARSER SPECIFICATIONS BEGIN HERE

void MailFile() :
	{
	}
{
  (
	{
	  count++;
	}
    MailMessage()
	{
	  System.out.print(count + ".");
	  System.out.flush();
	}
  )*
  <EOF>
	{
	  System.out.println("");
	  indstr.close();
	}
}

void MailMessage() :
	{
	  PrintWriter msgstr = null;
	  Token subj=null, from=null, date=null, body;
	  if (count >= beginAt) {
	    try {
	      msgstr = new PrintWriter(new FileWriter(count + ".html"));
	    } catch (IOException e) {
	      throw new Error();
	    }
	  }
	}
{
  ( subj=<SUBJECT> | from=<FROM> | date=<DATE> )+
	{
	  indstr.print("<a href=\"" + count + ".html\">");
	  if (subj == null) {
	    indstr.println("no subject</a><br>");
	  } else {
	    indstr.println(fix(subj.image) + "</a><br>");
	  }
	  if (count >= beginAt) {
	    msgstr.println("<title>" + ((subj==null) ? "no subject" : fix(subj.image)) + "</title>");
	    msgstr.println("Subject: " + ((subj==null) ? "no subject" : fix(subj.image)) + "<br>");
	    msgstr.println("From: " + ((from==null) ? "" : fix(from.image)) + "<br>");
	    msgstr.println("Date: " + ((date==null) ? "" : fix(date.image)) + "<br>");
            msgstr.println("<br>");
	  }
	}
  ( body=<BODY>
	{
	  if (count >= beginAt) {
	    msgstr.print(fix(body.image) + "<br>");
	  }
	}
  )*
  <END>
	{
	  if (count >= beginAt) {
	    msgstr.close();
	  }
	}
}


// LEXICAL SPECIFICATIONS BEGIN HERE

TOKEN:
{
  <#EOL: "\n" | "\r" | "\r\n">
|
  <#TWOEOLS: (("\n"|"\r\n") <EOL>) | ("\r\r" [ "\n" ])>
|
  <#NOT_EOL: ~["\n","\r"]>
}

<DEFAULT>
SKIP:
{
  < <EOL> "*** EOOH ***" <EOL> > : MAILHEADER
|
  <~[]>
}

<MAILHEADER>
SKIP:
{
  <_TWOEOLS: <TWOEOLS>> : MAILBODY
    // We cannot have just a reference to a regular expression in a
    // lexical specification - i.e., we cannot simply have <TWOEOLS>.
|
  "Subject: " : MAILSUBJECT
|
  "From: " : MAILFROM
|
  "Date: " : MAILDATE
|
  <~[]>
}

<MAILSUBJECT>
TOKEN:
{
  <SUBJECT: ( <NOT_EOL> )+>
}

<MAILSUBJECT>
SKIP:
{
  <_EOL1: <EOL>> : MAILHEADER
}

<MAILFROM>
TOKEN:
{
  <FROM: ( <NOT_EOL> )+>
}

<MAILFROM>
SKIP:
{
  <_EOL2: <EOL>> : MAILHEADER
}

<MAILDATE>
TOKEN:
{
  <DATE: ( <NOT_EOL> )+>
}

<MAILDATE>
SKIP:
{
  <_EOL3: <EOL>> : MAILHEADER
}

<MAILBODY>
TOKEN:
{
  <BODY: (~["\n","\r","\u001f"])* <EOL>>
|
  <END: "\u001f"> : DEFAULT
}
