Developer Forums | About Us | Site Map
Search  
HOME > TUTORIALS > SERVER SIDE CODING > PERL TUTORIALS > THE ROAD TO BETTER PROGRAMMING: CHAPTER 8. THE TOP LEVEL AND COMPOUND CLASS PARSERS


Sponsors





Useful Lists

Web Host
site hosted by netplex

Online Manuals

The road to better programming: Chapter 8. The top-level and compound-class parsers
By Teodor Zlatanov - 2004-03-22 Page:  1 2 3 4 5 6 7

The grammar basics

The top-level (global) parser is defined in the variable $parse_global. It is a global object and distinct from the second-level parsers, which are all referenced in the %parsers hash. Why not have $parsers{GLOBAL} instead of a separate variable? Because the top-level parser is so distinct and so independent of all the second-level parsers that grouping it with them in any way would, I felt, confuse the program structure.

The grammar consists of a Parse::RecDescent grammar definition interpreted in place by Parse::RecDescent. Thus, $parse_globalis a Parse::RecDescent object (a parser) with methods corresponding to the rules defined in the grammar.

The input() method and its corresponding grammar rule are essential. This is the only method I want from the top-level parser, since it unites all the other rules in one. It's recommended to have only one top rule in a grammar for clarity, unless you need to share grammar element definitions between several disjoint grammars. If that's the case, make sure you document your decision so a casual reader can immediately understand what's happening.



my $parse_global = new Parse::RecDescent (q{
  # note that the section has to come after the class
  # in the parsing order (it matches a class)
  input:  blank | comment | class_with_line | class | section | line_action

  comment: /^\s*/ '#' { 1; }
  blank: /^\s*$/ { 1; }

  section: /\w+/ ':' { $::current_section = $item[1]; $::current_classes = 'any'; 1; }

  class: compound_class '::' { $::current_classes = $item{compound_class}; 1; }

  class_with_line: compound_class '::' nonempty_line { $::current_classes = $item{compound_class};
                                              { 
                                                section => $::current_section, 
                                                classes => $::current_classes, 
                                                line => $item{nonempty_line} 
                                              };
                                           }

  line_action: line { 
                      { 
                        section => $::current_section, 
                        classes => $::current_classes, 
                        line => $item{line} 
                      }; 
                    }

  nonempty_line: /\S.*/

  line: /.*/

  compound_class: /[-!.|\w]+/

});



View The road to better programming: Chapter 8. The top-level and compound-class parsers Discussion

Page:  1 2 3 4 5 6 7 Next Page: The simple elements of the top-level parser

First published by IBM developerWorks


Copyright 2004-2024 GrindingGears.com. All rights reserved.
Article copyright and all rights retained by the author.