[antlr-interest] any comments on Mantra?

Terence Parr parrt at cs.usfca.edu
Sun Oct 14 09:55:14 PDT 2007


On Oct 13, 2007, at 9:28 PM, Rob Finneran wrote:

> Hello Fellow Listees,
>
> Can a programmer control how much gets piped as either a stream of
> line objects, or collection of line objects?
>
> For example, change
>
> File("coffee") => Lines() => MyFilter(".*parrt.*");
>
> to
>
> (File("coffee") => Lines()) => MyFilter(".*parrt.*");

Well, the parens really only affect precedence and are a no-op in  
this case.  Do

list lines = [];
File("coffee") => Lines() => lines;
lines => MyFilter(".*parrt.*");

or

lines : aprocessingmethodorclosure;

> The additional parens would tell it to send a collection of lines to
> MyFilter instead of calling MyFilter() in a for-each fashion with each
> line. (I realize that my example is poor because File() or maybe
> File()=>Lines() probably already generates a collection to begin with,
> does it not?.)
>
> The point I'm trying to make is that it should be able to accumulate a
> collection of piped objects before passing to the next element in the
> pipeline.

This is an important enough distinction that you should manually say  
"redirect to list".  There are some examples onthis.  Check out  
word_freq2.om vs word_freq.om in the tests dir.

> Sometimes you do not want to start processing the next step
> until you are completely sure that the first steps have already been
> completed.

correct.

> The canonical example might first read an entire file into memory as a
> collection of lines.  The next element in the pipeline would then be
> able to overwrite the original file, and without using a temp file,
> since the file's read-handle would already be closed. A converse
> example might pull items from a very long queue. In this case the
> for-each processing of each single object along the pipeline would
> likely be the desired approach.

Yep.  Take a look at the addlicense.om test.  I used it to add  
licenses to the source.  It takes care of open/close stuff so no need  
for temp file.  In fact, i have yet to call open on any file or  
stream yet manually!

/* Add license.txt to head of all file arguments on cmd-line */
string license = File("license.txt").contents();
args:{
     string filename |
     string fs = File(filename).contents();
     [license,fs] => File(filename);
};

// alternative:
//args:{ string filename | license+File(filename) => File(filename); };
// next won't work as File is evaluated inside list too late
//args:{ string filename | [license,File(filename)] => File 
(filename); };

So for lines, you can do File("foo").lines(), which is a list or File 
("foo") => Lines() => ... which is a pipe.

Ter


More information about the antlr-interest mailing list