5.6 Translating the Coffee Grammar to Code


 
Building Parsers with Java
By Steven  John  Metsker

Table of Contents
Chapter  5.   Parsing Data Languages

    Content

You can follow the rules of Section 3.6 "Translating a Grammar to Code," and code subparsers as methods on a parser class. Figure 5.4 shows CoffeeParser .

Figure 5.4. The CoffeeParser class. This class organizes its subparsers as individual methods.

graphics/05fig04.gif

Most of the methods of the CoffeeParser class return a parser that recognizes one aspect of the coffee grammar. For example, the price() method returns a parser for the rule

 price = Num; 

The code for CoffeeParser.price() plugs in the price assembler:

 /*   * Return a parser that will recognize the sequence:  *  *    price = Num;  *  * Use a PriceAssembler to update the target coffee object.  */ protected Parser price() {     return new Num().setAssembler(new PriceAssembler()); } 

The methods for some of the other subparsers are longer. For example, here is the code for CoffeeParser.roast() :

 /*   * Return a parser that will recognize the grammar:  *  *     roast = Word (orFrench  Empty);  *  * Use a RoastAssembler to update the target coffee object  * with the recognized Word; orFrench also uses an  * assembler.  */ protected Parser roast() {     Sequence s = new Sequence();     s.add(new Word().setAssembler(new RoastAssembler()));     Alternation a = new Alternation();     a.add(orFrench());     a.add(new Empty());     s.add(a);     return s; } 

To see the parser in action, consider reading a list of coffees from the file that contains the following:

 Brimful, Regular, Kenya, 6.95  Caress (Smackin), French, Sumatra, 7.95 Fragrant Delicto, Regular/French, Peru, 9.95 Havalavajava, Regular, Hawaii, 11.95 Launch Mi, French, Kenya, 6.95 Roman Spur (Revit), Italian, Guatemala, 7.95 Simplicity House, Regular/French, Colombia, 5.95 

The following code reads this file, creates a Coffee object for each line, and displays the object:

 package sjm.examples.coffee;  import java.io.*; import sjm.parse.*; import sjm.parse.tokens.*; /**  * Show the recognition of a list of types of coffee,  * reading from a file.  */ public class ShowCoffee { public static void main(String args[]) throws Exception {     InputStream is =         ClassLoader.getSystemResourceAsStream("coffee.txt");     BufferedReader r =         new BufferedReader(new InputStreamReader(is));     Tokenizer t = CoffeeParser.tokenizer();     Parser p = CoffeeParser.start();     while (true) {         String s = r.readLine();         if (s == null) {             break;         }         t.setString(s);         Assembly in = new TokenAssembly(t);         Assembly out = p.bestMatch(in);         System.out.println(out.getTarget());     } } } 

This file coffee.txt is on this book's CD. If you copy the file to any directory in your CLASSPATH, then ClassLoader will be able to find it. Run the program, and it will print the following:

 Brimful, Regular, Kenya, 6.95  Caress(Smackin), French, Sumatra, 7.95 Fragrant Delicto, Regular/French, Peru, 9.95 Havalavajava, Regular, Hawaii, 11.95 Launch Mi, French, Kenya, 6.95 Roman Spur(Revit), Italian, Guatemala, 7.95 Simplicity House, Regular/French, Colombia, 5.95 

This output differs from the input only with regard to some whitespace. The output shows, however, that you made the transition from text to objects and back to text.

Note that ShowCoffee.main() is careful to use the tokenizer that CoffeeParser provides. This tokenizer allows blanks to occur inside words after the first letter of the word. The main() routine gets a copy of this tokenizer and feeds it each line of the input file.


   
Top


Building Parsers with Java
Building Parsers With Javaв„ў
ISBN: 0201719622
EAN: 2147483647
Year: 2000
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net