001: /**
002: * java_cup.anttask.CUPTask.java
003: *
004: * @author Michael Petter, 2003
005: *
006: * Ant-Task for CUP Parser Generator for Java
007: * -- tested with Ant 1.5.1;
008: * -- compiles with javac -classpath .:${ANT_HOME}/lib/ant.jar java_cup.anttask.CUPTask.java
009: * -- overrides org.apache.tools.ant.taskdefs.Java
010: * -- providing cool interface to CUP
011: * -- mapping all existing parameters to attributes
012: * -- trys to add new useful features to CUP, like
013: * - automatic package discovery
014: * - re-generate .java only when necessary
015: * - possibility to generate into a dest-directory
016: *
017: * my code is not perfect (in some cases it is pretty
018: * ugly :-) ), but i didn't encounter any major error
019: * until now
020: */package java_cup.anttask;
021:
022: import org.apache.tools.ant.Task;
023: import org.apache.tools.ant.BuildException;
024: import org.apache.tools.ant.types.Path;
025:
026: import java.util.List;
027: import java.util.ArrayList;
028: import java.io.File;
029: import java.io.FileReader;
030: import java.io.BufferedReader;
031: import java.io.IOException;
032: import java.net.URL;
033:
034: import java_cup.version;
035:
036: public class CUPTask extends Task {
037: private String srcfile = null;
038: private String parser = null;
039: private String _package = null;
040: private String symbols = null;
041: private String destdir = null;
042: private boolean _interface = false;
043: private boolean nonterms = false;
044: private String expect = null;
045: private boolean compact_red = false;
046: private boolean nowarn = false;
047: private boolean nosummary = false;
048: private boolean progress = false;
049: private boolean dump_grammar = false;
050: private boolean dump_states = false;
051: private boolean dump_tables = false;
052: private boolean dump = false;
053: private boolean time = false;
054: private boolean debug = false;
055: private boolean nopositions = false;
056: private boolean noscanner = false;
057: private boolean force = false;
058: private boolean quiet = false;
059:
060: /**
061: * executes the task
062: * parses all attributes and validates options...
063: *
064: */
065:
066: public void execute() throws BuildException {
067: List sc = new ArrayList(); // sc = simulated commandline
068: // here, we parse our elements
069: if (parser != null) {
070: sc.add("-parser");
071: sc.add(parser);
072: } else
073: parser = "parser"; // set the default name to check actuality
074: if (_package != null) {
075: sc.add("-package");
076: sc.add(_package);
077: }
078: if (symbols != null) {
079: sc.add("-symbols");
080: sc.add(symbols);
081: } else
082: symbols = "sym";
083: if (expect != null) {
084: sc.add("-expect");
085: sc.add(expect);
086: }
087: if (_interface) {
088: sc.add("-interface");
089: }
090: if (nonterms) {
091: sc.add("-nonterms");
092: }
093: if (compact_red) {
094: sc.add("-compact_red");
095: }
096: if (nowarn) {
097: sc.add("-nowarn");
098: }
099: if (nosummary) {
100: sc.add("-nosummary");
101: }
102: if (progress) {
103: sc.add("-progress");
104: }
105: if (dump_grammar) {
106: sc.add("-dump_grammar");
107: }
108: if (dump_states) {
109: sc.add("-dump_states");
110: }
111: if (dump_tables) {
112: sc.add("-dump_tables");
113: }
114: if (dump) {
115: sc.add("-dump");
116: }
117: if (time) {
118: sc.add("-time");
119: }
120: if (debug) {
121: sc.add("-debug");
122: }
123: if (nopositions) {
124: sc.add("-nopositions");
125: }
126: if (noscanner) {
127: sc.add("-noscanner");
128: }
129: if (!quiet)
130: log("This is " + version.title_str);
131: if (!quiet)
132: log("Authors : " + version.author_str);
133: if (!quiet)
134: log("Bugreports to petter@cs.tum.edu");
135:
136: // look for package name and add to destdir
137: String packagename = inspect(srcfile);
138:
139: // now, that's sweet:
140: if (destdir == null) {
141: destdir = System.getProperty("user.dir");
142: if (!quiet)
143: log("No destination directory specified; using working directory: "
144: + destdir);
145: }
146: File dest = new File(destdir + packagename);
147: if (!(dest).exists()) {
148: if (!quiet)
149: log("Destination directory didn't exist; creating new one: "
150: + destdir + packagename);
151: dest.mkdirs();
152: force = true;
153: } else {
154: if (force && !quiet) {
155: log("anyway, this generation will be processed because of option force set to \"true\"");
156: } else {
157: if (!quiet)
158: log("checking, whether this run is necessary");
159: }
160: // let's check, whether there exists any Parser fragment...
161: File parserfile = new File(destdir + packagename, parser
162: + ".java");
163: File symfile = new File(destdir + packagename, symbols
164: + ".java");
165: File cupfile = new File(srcfile);
166:
167: if (!parserfile.exists() || !symfile.exists()) {
168: if (!quiet)
169: log("Either Parserfile or Symbolfile didn't exist");
170: force = true;
171: } else {
172: if (!quiet)
173: log("Parserfile and symbolfile are existing");
174: }
175:
176: if (parserfile.lastModified() <= cupfile.lastModified()) {
177: if (!quiet)
178: log("Parserfile " + parserfile + " isn't actual");
179: force = true;
180: } else {
181: if (!quiet)
182: log("Parserfile " + parserfile + " is actual");
183: }
184:
185: if (symfile.lastModified() <= cupfile.lastModified()) {
186: if (!quiet)
187: log("Symbolfile " + symfile + " isn't actual");
188: force = true;
189: } else {
190: if (!quiet)
191: log("Symbolfile" + symfile + " is actual");
192: }
193:
194: if (!force) {
195: if (!quiet)
196: log("skipping generation of " + srcfile);
197: if (!quiet)
198: log("use option force=\"true\" to override");
199: return;
200: }
201: }
202:
203: sc.add("-destdir");
204: sc.add(dest.getAbsolutePath());
205:
206: // also catch the not existing input file
207: if (srcfile == null)
208: throw new BuildException(
209: "Input file needed: Specify <cup srcfile=\"myfile.cup\"> ");
210: if (!(new File(srcfile)).exists())
211: throw new BuildException("Input file not found: srcfile=\""
212: + srcfile + "\" ");
213:
214: sc.add(srcfile);
215: String[] args = new String[sc.size()];
216: for (int i = 0; i < args.length; i++)
217: args[i] = (String) sc.get(i);
218:
219: try {
220: java_cup.Main.main(args);
221: } catch (Exception e) {
222: log("CUP error occured int CUP task: " + e);
223: }
224:
225: // this is a dirty hack to determine the apropriate class path
226: // URL url = CUPTask.class.getResource("/java_cup/Main.class");
227: // String path = url.getPath().substring(0,url.getPath().length()-20);
228: // // if called from a .jar or .zip remove the last "!"
229: // if (path.endsWith("!")) path=path.substring(0,path.length()-1);
230: // createClasspath().setPath(path);
231: //
232: // setFailonerror(true);
233: // setFork(true);
234: //
235:
236: // here, we prepare for calling CUP
237: // setClassname("java_cup.Main");
238:
239: // let's call CUP
240: // super.execute();
241:
242: }
243:
244: /**
245: * Let's search for package name
246: *
247: * @param cupfile where we have to search for the package name
248: *
249: * @return the package folder structure
250: */
251: protected String inspect(String cupfile) {
252: try {
253: BufferedReader br = new BufferedReader(new FileReader(
254: cupfile));
255: while (br.ready()) {
256: String line = br.readLine();
257: if ((line.startsWith("package"))
258: && (line.indexOf(";") != -1)) {
259: String result = line
260: .substring(8, line.indexOf(";"));
261: result = result.replace('.', System.getProperty(
262: "file.separator").charAt(0));
263: return System.getProperty("file.separator")
264: + result;
265: }
266:
267: }
268: } catch (IOException ioe) {
269: }
270: return "";
271: }
272:
273: /**
274: * Gets the value of quiet
275: *
276: * @return the value of quiet
277: */
278: public boolean getQuiet() {
279: return this .quiet;
280: }
281:
282: /**
283: * Sets the value of quiet
284: *
285: * @param arg_quiet Value to assign to this.quiet
286: */
287: public void setQuiet(boolean argquiet) {
288: this .quiet = argquiet;
289: }
290:
291: /**
292: * Gets the value of force
293: *
294: * @return the value of force
295: */
296: public boolean getForce() {
297: return this .force;
298: }
299:
300: /**
301: * Sets the value of force
302: *
303: * @param arg_package Value to assign to this.force
304: */
305: public void setForce(boolean argforce) {
306: this .force = argforce;
307: }
308:
309: /**
310: * Gets the value of _package
311: *
312: * @return the value of _package
313: */
314: public String getPackage() {
315: return this ._package;
316: }
317:
318: /**
319: * Sets the value of _package
320: *
321: * @param arg_package Value to assign to this._package
322: */
323: public void setPackage(String arg_package) {
324: this ._package = arg_package;
325: }
326:
327: /**
328: * Gets the value of destdir
329: *
330: * @return the value of destdir
331: */
332: public String getDestdir() {
333: return this .destdir;
334: }
335:
336: /**
337: * Sets the value of destdir
338: *
339: * @param arg_package Value to assign to this.destdir
340: */
341: public void setDestdir(String destdir) {
342: this .destdir = destdir;
343: }
344:
345: /**
346: * Gets the value of _interface
347: *
348: * @return the value of _interface
349: */
350: public boolean isInterface() {
351: return this ._interface;
352: }
353:
354: /**
355: * Sets the value of _interface
356: *
357: * @param arg_interface Value to assign to this._interface
358: */
359: public void setInterface(boolean arg_interface) {
360: this ._interface = arg_interface;
361: }
362:
363: /**
364: * Get the Srcfile value.
365: * @return the Srcfile value.
366: */
367: public String getSrcfile() {
368: return srcfile;
369: }
370:
371: /**
372: * Set the Srcfile value.
373: * @param newSrcfile The new Srcfile value.
374: */
375: public void setSrcfile(String newSrcfile) {
376: this .srcfile = newSrcfile;
377: }
378:
379: /**
380: * Gets the value of parser
381: *
382: * @return the value of parser
383: */
384: public String getParser() {
385: return this .parser;
386: }
387:
388: /**
389: * Sets the value of parser
390: *
391: * @param argParser Value to assign to this.parser
392: */
393: public void setParser(String argParser) {
394: this .parser = argParser;
395: }
396:
397: /**
398: * Gets the value of symbols
399: *
400: * @return the value of symbols
401: */
402: public String getSymbols() {
403: return this .symbols;
404: }
405:
406: /**
407: * Sets the value of symbols
408: *
409: * @param argSymbols Value to assign to this.symbols
410: */
411: public void setSymbols(String argSymbols) {
412: this .symbols = argSymbols;
413: }
414:
415: /**
416: * Gets the value of nonterms
417: *
418: * @return the value of nonterms
419: */
420: public boolean isNonterms() {
421: return this .nonterms;
422: }
423:
424: /**
425: * Sets the value of nonterms
426: *
427: * @param argNonterms Value to assign to this.nonterms
428: */
429: public void setNonterms(boolean argNonterms) {
430: this .nonterms = argNonterms;
431: }
432:
433: /**
434: * Gets the value of expect
435: *
436: * @return the value of expect
437: */
438: public String getExpect() {
439: return this .expect;
440: }
441:
442: /**
443: * Sets the value of expect
444: *
445: * @param argExpect Value to assign to this.expect
446: */
447: public void setExpect(String argExpect) {
448: this .expect = argExpect;
449: }
450:
451: /**
452: * Gets the value of compact_red
453: *
454: * @return the value of compact_red
455: */
456: public boolean isCompact_red() {
457: return this .compact_red;
458: }
459:
460: /**
461: * Sets the value of compact_red
462: *
463: * @param argCompact_red Value to assign to this.compact_red
464: */
465: public void setCompact_red(boolean argCompact_red) {
466: this .compact_red = argCompact_red;
467: }
468:
469: /**
470: * Gets the value of nowarn
471: *
472: * @return the value of nowarn
473: */
474: public boolean isNowarn() {
475: return this .nowarn;
476: }
477:
478: /**
479: * Sets the value of nowarn
480: *
481: * @param argNowarn Value to assign to this.nowarn
482: */
483: public void setNowarn(boolean argNowarn) {
484: this .nowarn = argNowarn;
485: }
486:
487: /**
488: * Gets the value of nosummary
489: *
490: * @return the value of nosummary
491: */
492: public boolean isNosummary() {
493: return this .nosummary;
494: }
495:
496: /**
497: * Sets the value of nosummary
498: *
499: * @param argNosummary Value to assign to this.nosummary
500: */
501: public void setNosummary(boolean argNosummary) {
502: this .nosummary = argNosummary;
503: }
504:
505: /**
506: * Gets the value of progress
507: *
508: * @return the value of progress
509: */
510: public boolean isProgress() {
511: return this .progress;
512: }
513:
514: /**
515: * Sets the value of progress
516: *
517: * @param argProgress Value to assign to this.progress
518: */
519: public void setProgress(boolean argProgress) {
520: this .progress = argProgress;
521: }
522:
523: /**
524: * Gets the value of dump_grammar
525: *
526: * @return the value of dump_grammar
527: */
528: public boolean isDump_grammar() {
529: return this .dump_grammar;
530: }
531:
532: /**
533: * Sets the value of dump_grammar
534: *
535: * @param argDump_grammar Value to assign to this.dump_grammar
536: */
537: public void setDump_grammar(boolean argDump_grammar) {
538: this .dump_grammar = argDump_grammar;
539: }
540:
541: /**
542: * Gets the value of dump_states
543: *
544: * @return the value of dump_states
545: */
546: public boolean isDump_states() {
547: return this .dump_states;
548: }
549:
550: /**
551: * Sets the value of dump_states
552: *
553: * @param argDump_states Value to assign to this.dump_states
554: */
555: public void setDump_states(boolean argDump_states) {
556: this .dump_states = argDump_states;
557: }
558:
559: /**
560: * Gets the value of dump_tables
561: *
562: * @return the value of dump_tables
563: */
564: public boolean isDump_tables() {
565: return this .dump_tables;
566: }
567:
568: /**
569: * Sets the value of dump_tables
570: *
571: * @param argDump_tables Value to assign to this.dump_tables
572: */
573: public void setDump_tables(boolean argDump_tables) {
574: this .dump_tables = argDump_tables;
575: }
576:
577: /**
578: * Gets the value of dump
579: *
580: * @return the value of dump
581: */
582: public boolean isDump() {
583: return this .dump;
584: }
585:
586: /**
587: * Sets the value of dump
588: *
589: * @param argDump Value to assign to this.dump
590: */
591: public void setDump(boolean argDump) {
592: this .dump = argDump;
593: }
594:
595: /**
596: * Gets the value of time
597: *
598: * @return the value of time
599: */
600: public boolean isTime() {
601: return this .time;
602: }
603:
604: /**
605: * Sets the value of time
606: *
607: * @param argTime Value to assign to this.time
608: */
609: public void setTime(boolean argTime) {
610: this .time = argTime;
611: }
612:
613: /**
614: * Gets the value of debug
615: *
616: * @return the value of debug
617: */
618: public boolean isDebug() {
619: return this .debug;
620: }
621:
622: /**
623: * Sets the value of debug
624: *
625: * @param argDebug Value to assign to this.debug
626: */
627: public void setDebug(boolean argDebug) {
628: this .debug = argDebug;
629: }
630:
631: /**
632: * Gets the value of nopositions
633: *
634: * @return the value of nopositions
635: */
636: public boolean isNopositions() {
637: return this .nopositions;
638: }
639:
640: /**
641: * Sets the value of nopositions
642: *
643: * @param argNopositions Value to assign to this.nopositions
644: */
645: public void setNopositions(boolean argNopositions) {
646: this .nopositions = argNopositions;
647: }
648:
649: /**
650: * Gets the value of noscanner
651: *
652: * @return the value of noscanner
653: */
654: public boolean isNoscanner() {
655: return this .noscanner;
656: }
657:
658: /**
659: * Sets the value of noscanner
660: *
661: * @param argNoscanner Value to assign to this.noscanner
662: */
663: public void setNoscanner(boolean argNoscanner) {
664: this.noscanner = argNoscanner;
665: }
666:
667: }
|