Browse Source

Extend the range of options ANTLR task is able to deal with

Submitted by:
Stephen Chin, aphid@versionablestore.com


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272941 13f79535-47bb-0310-9956-ffa450edef68
master
Stephane Bailliez 23 years ago
parent
commit
270394a09f
5 changed files with 289 additions and 8 deletions
  1. +65
    -0
      docs/manual/OptionalTasks/antlr.html
  2. +38
    -2
      src/etc/testcases/taskdefs/optional/antlr/antlr.xml
  3. +7
    -0
      src/etc/testcases/taskdefs/optional/antlr/extended.calc.g
  4. +121
    -6
      src/main/org/apache/tools/ant/taskdefs/optional/ANTLR.java
  5. +58
    -0
      src/testcases/org/apache/tools/ant/taskdefs/optional/ANTLRTest.java

+ 65
- 0
docs/manual/OptionalTasks/antlr.html View File

@@ -54,6 +54,71 @@
</td> </td>
<td valign="top" align="center">No</td> <td valign="top" align="center">No</td>
</tr> </tr>
<tr>
<td valign="top">glib</td>
<td valign="top">
An optional super grammar file that the target grammar overrides. This
feature is only needed for advanced vocabularies.
</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">debug</td>
<td valign="top">
When set to "yes", this flag adds code to the generated parser that will
launch the ParseView debugger upon invocation. The default is "no".
<br>
Note: ParseView is a separate component that needs to be installed or your
grammar will have compilation errors.
</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">html</td>
<td valign="top">
Emit an html version of the grammar with hyperlinked actions.
</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">diagnostic</td>
<td valign="top">
Generates a text file with debugging infomation based on the target grammar.
</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">trace</td>
<td valign="top">
Forces <b>all</b> rules to call traceIn/traceOut if set to "yes".
The default is "no".
</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">traceParser</td>
<td valign="top">
Only forces parser rules to call traceIn/traceOut if set to "yes".
The default is "no".
</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">traceLexer</td>
<td valign="top">
Only forces lexer rules to call traceIn/traceOut if set to "yes".
The default is "no".
</td>
<td valign="top" align="center">No</td>
</tr>
<tr>
<td valign="top">traceTreeWalker</td>
<td valign="top">
Only forces tree walker rules to call traceIn/traceOut if set to
"yes". The default is "no".
</td>
<td valign="top" align="center">No</td>
</tr>
<!--tr> <!--tr>
<td valign="top">fork</td> <td valign="top">fork</td>
<td valign="top">Run ANTLR in a separate VM.</td> <td valign="top">Run ANTLR in a separate VM.</td>


+ 38
- 2
src/etc/testcases/taskdefs/optional/antlr/antlr.xml View File

@@ -40,10 +40,46 @@


<target name="test7"> <target name="test7">
<antlr target="antlr.xml"/> <antlr target="antlr.xml"/>
</target>
</target>

<target name="test8">
<antlr target="extended.calc.g" outputdirectory="${tmp.dir}" glib="non-existant-file.g"/>
</target>

<target name="test9">
<mkdir dir="${tmp.dir}"/>
<!-- Note that I had to copy the grammars over to the temporary directory. -->
<!-- This is because ANTLR expects the super grammar and its generated java -->
<!-- files to be in the same directory, which won't be the case if I use -->
<!-- the output directory option. -->
<copy file="antlr.g" todir="${tmp.dir}"/>
<copy file="extended.calc.g" todir="${tmp.dir}"/>
<antlr target="${tmp.dir}/antlr.g"/>
<antlr target="${tmp.dir}/extended.calc.g" glib="${tmp.dir}/antlr.g"/>
</target>

<target name="test10">
<mkdir dir="${tmp.dir}"/>
<antlr target="antlr.g" outputdirectory="${tmp.dir}" html="yes"/>
</target>

<target name="test11">
<mkdir dir="${tmp.dir}"/>
<antlr target="antlr.g" outputdirectory="${tmp.dir}" diagnostic="yes"/>
</target>

<target name="test12">
<mkdir dir="${tmp.dir}"/>
<antlr target="antlr.g" outputdirectory="${tmp.dir}" trace="yes"/>
</target>

<target name="test13">
<mkdir dir="${tmp.dir}"/>
<antlr target="antlr.g" outputdirectory="${tmp.dir}" traceLexer="yes" traceParser="yes" traceTreeWalker="yes"/>
</target>


<target name="cleanup"> <target name="cleanup">
<delete dir="${tmp.dir}" /> <delete dir="${tmp.dir}" />
</target> </target>


</project>
</project>

+ 7
- 0
src/etc/testcases/taskdefs/optional/antlr/extended.calc.g View File

@@ -0,0 +1,7 @@
// Not really a great extension, but it is only a test after all!

class ExtendedCalcParser extends CalcParser;

exprList
: LPAREN (expr)* RPAREN
;

+ 121
- 6
src/main/org/apache/tools/ant/taskdefs/optional/ANTLR.java View File

@@ -74,6 +74,7 @@ import org.apache.tools.ant.types.Path;
* *
* @author <a href="mailto:emeade@geekfarm.org">Erik Meade</a> * @author <a href="mailto:emeade@geekfarm.org">Erik Meade</a>
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> * @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a>
* @author <a href="mailto:aphid@browsecode.org">Stephen Chin</a>
*/ */
public class ANTLR extends Task { public class ANTLR extends Task {


@@ -85,6 +86,30 @@ public class ANTLR extends Task {
/** where to output the result */ /** where to output the result */
private File outputDirectory; private File outputDirectory;


/** an optional super grammar file */
private String superGrammar;

/** optional flag to enable parseView debugging */
private boolean debug;

/** optional flag to enable html output */
private boolean html;

/** optional flag to print out a diagnostic file */
private boolean diagnostic;

/** optional flag to add trace methods */
private boolean trace;

/** optional flag to add trace methods to the parser only */
private boolean traceParser;

/** optional flag to add trace methods to the lexer only */
private boolean traceLexer;

/** optional flag to add trace methods to the tree walker only */
private boolean traceTreeWalker;

/** should fork ? */ /** should fork ? */
private final boolean fork = true; private final boolean fork = true;


@@ -106,15 +131,70 @@ public class ANTLR extends Task {
this.outputDirectory = outputDirectory; this.outputDirectory = outputDirectory;
} }


/**
* Sets an optional super grammar file
*/
public void setGlib(String superGrammar) {
this.superGrammar = superGrammar;
}
/**
* Sets a flag to enable ParseView debugging
*/
public void setDebug(boolean enable) {
debug = enable;
}
/**
* Sets a flag to emit html
*/
public void setHtml(boolean enable) {
html = enable;
}

/**
* Sets a flag to emit diagnostic text
*/
public void setDiagnostic(boolean enable) {
diagnostic = enable;
}
/**
* Sets a flag to enable all tracing
*/
public void setTrace(boolean enable) {
trace = enable;
}
/**
* Sets a flag to enable parser tracing
*/
public void setTraceParser(boolean enable) {
traceParser = enable;
}
/**
* Sets a flag to allow the user to enable lexer tracing
*/
public void setTraceLexer(boolean enable) {
traceLexer = enable;
}
/**
* Sets a flag to allow the user to enable tree walker tracing
*/
public void setTraceTreeWalker(boolean enable) {
traceTreeWalker = enable;
}
// we are forced to fork ANTLR since there is a call // we are forced to fork ANTLR since there is a call
// to System.exit() and there is nothing we can do // to System.exit() and there is nothing we can do
// right now to avoid this. :-( (SBa) // right now to avoid this. :-( (SBa)
// I'm not removing this method to keep backward compatibility // I'm not removing this method to keep backward compatibility
// and
public void setFork(boolean s) { public void setFork(boolean s) {
//this.fork = s; //this.fork = s;
} }

/** /**
* The working directory of the process * The working directory of the process
*/ */
@@ -184,10 +264,9 @@ public class ANTLR extends Task {
validateAttributes(); validateAttributes();
//TODO: use ANTLR to parse the grammer file to do this. //TODO: use ANTLR to parse the grammer file to do this.
if (target.lastModified() > getGeneratedFile().lastModified()) { if (target.lastModified() > getGeneratedFile().lastModified()) {
commandline.createArgument().setValue("-o");
commandline.createArgument().setValue(outputDirectory.toString());
populateAttributes();
commandline.createArgument().setValue(target.toString()); commandline.createArgument().setValue(target.toString());
log(commandline.describeCommand(), Project.MSG_VERBOSE); log(commandline.describeCommand(), Project.MSG_VERBOSE);
int err = run(commandline.getCommandline()); int err = run(commandline.getCommandline());
if (err == 1) { if (err == 1) {
@@ -198,11 +277,47 @@ public class ANTLR extends Task {
} }
} }


/**
* A refactored method for populating all the command line arguments based
* on the user-specified attributes.
*/
private void populateAttributes() {
commandline.createArgument().setValue("-o");
commandline.createArgument().setValue(outputDirectory.toString());
if (superGrammar != null) {
commandline.createArgument().setValue("-glib");
commandline.createArgument().setValue(superGrammar);
}
if (html) {
commandline.createArgument().setValue("-html");
}
if (diagnostic) {
commandline.createArgument().setValue("-diagnostic");
}
if (trace) {
commandline.createArgument().setValue("-trace");
}
if (traceParser) {
commandline.createArgument().setValue("-traceParser");
}
if (traceLexer) {
commandline.createArgument().setValue("-traceLexer");
}
if (traceTreeWalker) {
commandline.createArgument().setValue("-traceTreeWalker");
}
}

private void validateAttributes() throws BuildException { private void validateAttributes() throws BuildException {
if (target == null || !target.isFile()) { if (target == null || !target.isFile()) {
throw new BuildException("Invalid target: " + target); throw new BuildException("Invalid target: " + target);
} }

// validate the superGrammar file
if (superGrammar != null && !new File(superGrammar).isFile()) {
throw new BuildException("Invalid super grammar file: " + superGrammar);
}
// if no output directory is specified, used the target's directory // if no output directory is specified, used the target's directory
if (outputDirectory == null) { if (outputDirectory == null) {
String fileName = target.toString(); String fileName = target.toString();


+ 58
- 0
src/testcases/org/apache/tools/ant/taskdefs/optional/ANTLRTest.java View File

@@ -68,6 +68,7 @@ import org.apache.tools.ant.BuildFileTest;
* system classpath. (see ANTLR install.html) * system classpath. (see ANTLR install.html)
* *
* @author Erik Meade <emeade@geekfarm.org> * @author Erik Meade <emeade@geekfarm.org>
* @author Stephen Chin <aphid@browsecode.org>
*/ */
public class ANTLRTest extends BuildFileTest { public class ANTLRTest extends BuildFileTest {


@@ -117,6 +118,57 @@ public class ANTLRTest extends BuildFileTest {
public void test7() { public void test7() {
expectBuildException("test7", "Unable to determine generated class"); expectBuildException("test7", "Unable to determine generated class");
} }

/**
* This is a negative test for the super grammar (glib) option.
*/
public void test8() {
expectBuildException("test8", "Invalid super grammar file");
}

/**
* This is a positive test for the super grammar (glib) option. ANTLR
* will throw an error if everything is not correct.
*/
public void test9() {
executeTarget("test9");
}

/**
* This test creates an html-ized version of the calculator grammar.
* The sanity check is simply whether or not an html file was generated.
*/
public void test10() {
executeTarget("test10");
File outputDirectory = new File(TASKDEFS_DIR + "antlr.tmp");
String[] calcFiles = outputDirectory.list(new HTMLFilter());
assertEquals(1, calcFiles.length);
}

/**
* This is just a quick sanity check to run the diagnostic option and
* make sure that it doesn't throw any funny exceptions.
*/
public void test11() {
executeTarget("test11");
}

/**
* This is just a quick sanity check to run the trace option and
* make sure that it doesn't throw any funny exceptions.
*/
public void test12() {
executeTarget("test12");
}

/**
* This is just a quick sanity check to run all the rest of the
* trace options (traceLexer, traceParser, and traceTreeWalker) to
* make sure that they don't throw any funny exceptions.
*/
public void test13() {
executeTarget("test13");
}
} }


class CalcFileFilter implements FilenameFilter { class CalcFileFilter implements FilenameFilter {
@@ -124,3 +176,9 @@ class CalcFileFilter implements FilenameFilter {
return name.startsWith("Calc"); return name.startsWith("Calc");
} }
} }

class HTMLFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return name.endsWith("html");
}
}

Loading…
Cancel
Save