Skip to content
Snippets Groups Projects
def.pl 28.78 KiB
#!/usr/local/bin/perl

# Perl script to parse VRPN message parameter declarations
# from a definition file (def-file) and then build
# an associative array to define them.
# The script then reads in one or more code files
# and inserts code in them based on keywords in the code
# files and the message parameters defined in the def-file.

# usage:  def.pl <def-file-name> <code-file-name>+

# Tom Hudson, June 1999

# Recursive descent parser pointed out by Chris Weigle.
# A redesign might use half-a-dozen RDParsers instead of two.

use Parse::RecDescent;
#$::RD_HINT = 1;     # turn on verbose debugging
#$::RD_TRACE = 1;     # turn on verbose debugging

local (%messageDefinitionArray) = ();
local ($numDefinitions) = 0;

# debugging flags

local ($dumpMessageArray) = 0;

# Tie::IxHash allows us to retrieve from the hash table in
# insertion order, which would be esp. nice for debugging.

# use Tie::IxHash;
# tie %messageDefinitionArray, "Tie::IxHash";

# If this were a full-featured language, we'd use a data structure
# to hold the syntax tree we create for the data types.  However,
# Perl (to the best of my knowledge) doesn't have data structures,
# so we have to encode it in a string, then parse that string
# every time we want to read it.
# One way to do this would be to have a recursive descent parser
# for every output, but instead we rewrite the standard definition
# into a simpler format that we don't need a RD parser to parse.
# BNF looks something like:
#  typeRecord:       typeEntry
#                  | typeEntry ':' typeRecord
#  typeEntry:        typeName variableName optionalArray
#                  | 'struct' typeName '{'
#                     structTypeRecord
#                    '}' variableName optionalArray
#  structTypeRecord: typeEntry
#                  | typeEntry ';' structTypeRecord
#  optionalArray:    count
#                  | empty
# Probably should have done it using many RD parsers, especially
# since they seem to be reentrant.

$definitionGrammar = q[

  start: line(s)

  line: /VRPN_MESSAGE/ typeName /{/ structOrFieldSequence /}/
    { $main::messageDefinitionArray{$item[2]} = $item[4];
      #  print $item[2] . " is " . $item[4] . "\n";
      $main::numDefinitions++; }
    | /[^\n]*\n/
    { }

  typeName: /(\w)+/
    { $return = $item[1]; }

  structOrFieldSequence: