72
CHAPTER 4
B
UILDING
SIMPLE
GENERATORS
We would like to take the names of these legends of computer science and store them
in C as an array of structures, as shown here: 
struct {
char *first;
char *last;
} g_names[] = 
{ "Larry","Wall" },
{ "Brian","Kerninghan" },
{ "Dennis","Ritchie" },
{ "","" }
};
This code munger is different from the previous code mungers because it uses an ERb
template to generate the output code. The Ruby portion of the generator is shown in
listing 4.8 and the template is shown in listing 4.9.
require "erb/erb"
Name = Struct.new( "Name", :first, :last )                               
names = []
File.open( "data.txt" ).each_line { |line|         
name = Name.new()               
( name.first, name.last ) = line.split( "," ).map{ |val| val.chomp }   
names.push( name )                     
}
erb = ERb.new( File.open( "data.template.c" ).read )                     
new_code = erb.result( binding )                                         
file_name = "data.c"                                                     
print "Creating #{file_name}\n"                                          
File.open( file_name, "w" ).write( new_code )                            
q
The Struct class facilitates the creation of classes that are just structures. In this case,
we create a new class called 
Name
with the member variables first and last. The
Struct builder also creates get and set methods for each field. In this case, it means that
you can use the obj.last or obj.last = "smith".
w
Here we split the line into its two components, the first and last names, which are
delimited by a comma. The map method is used to iterate over the fields and to remove
any trailing carriage returns by calling the chomp method on each item.
Listing 4.8 8 Listing 4.8 Code munger 5: Creates C constants from a CSV file
Gets the first
and last names
w
Creates a new 
Name structure
q
Creates the 
output file
e
Reads the data file
Creates a new Name object
Adds the Name 
object to the list
Runs the 
ERb template
Pdf text box font size - Compress reduce PDF size in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
C# Code & .NET API to Compress & Decompress PDF Document
pdf change font size; advanced pdf compressor online
Pdf text box font size - VB.NET PDF File Compress Library: Compress reduce PDF size in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
VB.NET PDF Document Compression and Decompression Control SDK
pdf reduce file size; pdf files optimized
T
HE
CODE
MUNGER
GENERATOR
TYPE
73
e
This code builds and executes the ERb template for the C data file. The template is run
when the result method is called. The local variables are passed in by using the
binding method.
struct {
char *first;
char *last;
} g_names[] = 
{ <% names.each { |name| %>
{ <%= name.first %>,<%= name.last %> },
<% } %> 
{ "", "" }
};
Code munger 6: building base classes
The last code munger in this chapter shows an easy way of building base classes with
rudimentary functionality; you can then derive from those classes to create a com-
pleted product.
This may seem a little backward, but it will make sense by the end of the example.
You start with the derived class. The base class is specified by the derived class, but
the base class itself does not yet exist. The derived class has some comments that spec-
ify the design of the base class. The derived class is fed into the code munger, which
creates the base class using these instructions. The derived class and base class are then
compiled to create the output. This flow is shown in figure 4.7.
This example builds base classes that are primitive data structure objects. A data
structure object contains only private instance variables and simple get and set
Listing 4.9 9 Template for code munger 5
Outputs the first and last name
Iterates through each name
DerivedClassFile
CodeMunger
OutputBaseClass
SourceCode
Compiler
Executable
Templates
DerivedClassCustom
SourceCode
Figure 4.7
The inputs and output for 
flow for code munger 6
C# PDF Annotate Library: Draw, edit PDF annotation, markups in C#.
Provide users with examples for adding text box to PDF and edit font size and color in text box field in C#.NET program. C#.NET: Draw Markups on PDF File.
change paper size in pdf document; adjust pdf page size
C# PDF insert text Library: insert text into PDF content in C#.net
Powerful .NET PDF edit control allows modify existing scanned PDF text. Ability to change text font, color, size and location and output a new PDF document.
apple compress pdf; pdf paper size
74
CHAPTER 4
B
UILDING
SIMPLE
GENERATORS
methods to alter the values. These types of classes are grunt work to build so they are
ideal for a simple generator.
Let’s start with the derived class:
// @field first
// @field middle
// @field last
public class Person extends PersonBase
{
public String toString()
{
return _first + " " + _middle + " " + _last;
}
}
Here we have created a new class called Person, which should inherit from the as-yet
nonexistent base class PersonBasePersonBase will be created by the generator.
We would like the Person class to have three fields: first, middle, and last. To make
that happen, we write the three comments at the top of the file; they start with //
@field. These comments tell the generator that the base class should have three
fields: first, middle, and last. You could add an extension to handle types.
The base class looks like this:
public class PersonBase {
protected String _first;
protected String _middle;
protected String _last;
public PersonBase()
_first = new String();
_middle = new String();
_last = new String();
}
public String getFirst() {
return _first;
}
public void setFirst( String value ) {
_first = value;
}
public String getMiddle() {
return _middle;
}
public void setMiddle( String value ) {
_middle = value;
}
public String getLast() {
return _last;
C# PDF Text Box Edit Library: add, delete, update PDF text box in
Support to change font color in PDF text box. Ability to change text size in PDF text box. Adding text box is another way to add text to PDF page.
can a pdf be compressed; change font size pdf text box
VB.NET PDF insert text library: insert text into PDF content in vb
Save text font, color, size and location changes to Other robust text processing features, like delete and remove PDF text, add PDF text box and field.
change font size in pdf file; best way to compress pdf files
T
HE
CODE
MUNGER
GENERATOR
TYPE
75
}
public void setLast( String value ) {
_last = value;
}
}
This base class has the three instance variable declarations: the constructor, and the get
and set methods for each instance. We removed the JavaDoc comments for brevity. You
need to make sure that the output has JavaDoc when a generator such as this is used in
production.
The Ruby code for the generator is shown in listing 4.10. It is similar to the gen-
erators we examined at the beginning of this chapter. The new feature is the use of
an ERb template to build the output.
require "erb/erb"
unless ARGV[0]
print "cm6 usage: cm6 file.java\n"
exit
end
fh = File.open( ARGV[0] )                                       
text = fh.read()                                                
fh.close                                                        
class_name = ARGV[0]                                            
class_name.gsub!( /[.]java$/, "" )                              
new_class_name = "#{class_name}Base"
fields = []
text.scan( /\/\/\s+@field\s+(.*?)\n/m ) { fields.push( $1 ) }   
erb = ERb.new( File.open( "base.template.java" ).read )         
new_code = erb.result( binding )                                
print "Creating #{new_class_name}.java\n"        
File.open( "#{new_class_name}.java", "w" ).write( new_code )    
q
This regular expression replacement code finds the .java at the end of the filename
and replaces it with a null string, effectively removing it. The regular expression is
shown in more detail in figure 4.8.
Listing 4.10 0 Code munger 6: Creates Java base classes for data storage
Reads the 
input file
Creates the 
output file
q
Creates the new
filename
w
Reads the 
@field comments
e
Runs the ERb 
template
[.]java$
Theendof
theline
The'.'
character
Thetext'java'
Figure 4.8
A regular expression 
that finds 
.java
C# PDF Convert to Word SDK: Convert PDF to Word library in C#.net
PDF document, keeps the elements (like images, tables and chats) of original PDF file and maintains the original text style (including font, size, color, links
compress pdf; change file size of pdf
VB.NET PDF delete text library: delete, remove text from PDF file
Functionality to remove text format by modifying text font, size, color, etc. Other PDF edit functionalities, like add PDF text, add PDF text box and field.
change font size pdf fillable form; best way to compress pdf file
76
CHAPTER 4
B
UILDING
SIMPLE
GENERATORS
w
This regular expression finds the // @field field-name comments in the file.
The field name is put into $1. Figure 4.9 is a diagram of the regular expression broken
out into more detail. The steeplechase segment at the beginning (\/\/) corresponds to
the two forward slashes at the start of the comment. After that, we look for some white
space (\s+), the text @field, and some more white space (\s+). Then we group all
of the text together before the return (\n).
e
Here you create the ERb object with the contents of the template file. Run the template
to get the output text. The call to binding gives the ERb template access to all of the
variables and functions within the current scope.
Listing 4.11 shows the ERb template that is used by code munger 6.
public class <%= new_class_name %> {          
<% fields.each { |field| %>                                           
protected String _<%= field %>;<% } %>                              
public <%= new_class_name %>()                                      
{ <% fields.each { |field| %>                                       
_<%= field %> = new String();<% } %>                             
}
<% fields.each { |field| %>                                           
public String get<%= field.capitalize %>() {                        
return _<%= field %>;                                              
                                                                  
public void set<%= field.capitalize %>( String value ) {            
_<%= field %> = value;                                            
                                                                  
<% } %>
}
q
Here the template uses the each iterator on the fields variable to build each
field definition.
\/\/\s+@field\s+(.*?)\n
Thetext'@field'
Oneormorewhitespacecharacters
Anytypeoftextgroupedtogetheras
$1
Acarriage
return
Theleadingforwardslashes
Figure 4.9 9 A regular expression for finding a field definition comment
Listing 4.11 1 Base.template.java 
Creates the 
constructor
w
Creates each 
instance variable
q
e
Creates 
get and set 
methods
Builds the 
class name
C# PDF delete text Library: delete, remove text from PDF file in
Functionality to remove text format by modifying text font, size, color, etc. Other PDF edit functionalities, like add PDF text, add PDF text box and field.
pdf page size limit; change font size fillable pdf
C# PDF Sticky Note Library: add, delete, update PDF note in C#.net
Allow users to add comments online in ASPX webpage. Able to change font size in PDF comment box. Able to save and print sticky notes in PDF file.
can pdf files be compressed; batch pdf compression
T
HE
CODE
MUNGER
GENERATOR
TYPE
77
w
Next, we use the fields array to create 
new
invocations for each of the fields in
the structure.
e
The fields array builds the get and set methods. The capitalize method capi-
talizes the first character of the string.
4.1.2
Developing the generator
Developing a code munger is straightforward. The process flow in figure 4.10 shows
the steps involved.
Let’s look at these steps in more detail:
• Build output test code—First, determine what the output is supposed to look like.
That will give you a target to shoot for and will make it easy to figure out what
you need to extract from the input files.
• Design the generator—How should the code munger get its input? How should it
parse the input? How should the output be built—using templates or just by
printing the output? You should work out these issues before diving into the code.
• Develop the input parser—The first coding step is to write the input processor.
This code will read the input file and extract the information from it that is
required to build the output.
• Develop templates from the test code—Once the input is handled, the next step is
to take the output test code that was originally developed and use it to either cre-
ate templates or build the code that will create the output.
• Develop the output code builder—The last step is to write the glue that takes the
data extracted by the input parser and feed it to the output formatter. Then, you
must store the output in the appropriate output files.
This is not meant to be a blueprint for your development. Each code munger is slightly
different, and you’ll add and remove development phases accordingly.
BuildOutputTestCode
DesignGenerator
DevelopTemplates
FromTestCode
DevelopInputParser
DevelopOutputCode
Builder
Figure 4.10  
The design and implementation 
steps for developing a code munger
78
CHAPTER 4
B
UILDING
SIMPLE
GENERATORS
4.2
T
HE
INLINE
-
CODE
EXPANSION
GENERATOR
MODEL
Inline-code expansion is an easy way to simplify source code. Sometimes your source
code is so mired in infrastructure work that the actual purpose of the code gets lost in
its implementation. Inline-code expansion simplifies your code by adding support for
a specialized syntax, in which you specify the requirements for the code to be gener-
ated. This syntax is parsed by the generator, which then implements code based on
the requirements.
A standard use of inline-code expansion is embedding SQL statements within
code. SQL access requires a lot of infrastructure: you have to get the database con-
nection handle, prepare the SQL, marshal the arguments, run the command, and
parse and store the output. All of this infrastructure code obscures the fact that you
are running a simple SELECT. The goal of inline expansion is to allow the engineer
to concentrate on the SQL syntax and leave the infrastructure code to the generator.
Here is an example of some code marked up with an inline SQL statement, which
is fed into the generator as input: 
void main( int argc, char *argv[] )
{
<sql-select: SELECT first, last FROM names>
return;
}
The output of the generator is:
void main( int argc, char *argv[] )
{
struct {
char *first;
char *last;
} *sql_output_1;
{
db_connection *db = get_connection();
sql_statement *sth = db->prepare( "SELECT first, last FROM names" );
sth->execute();
sql_output_1 = malloc( sizeof( *sql_output_1 ) * sth->count() );
for( long index = 0; index < sth->count(); index++ )
{
// ... marshal data
}
}
return;
}
This output is C pseudo-code and not for any particular SQL access system, but it
demonstrates that the actual intent of the original SELECT statement is lost in a quag-
mire of code.
T
HE
INLINE
-
CODE
EXPANSION
GENERATOR
MODEL
79
In this example, we have created a new language on top of C; let’s call it SQL-C.
The job of the generator is to convert SQL-C into production C for the compiler.
From the design and implementation perspective, the inline-code expander model
is a formalized code munger. The input is source code from any computer language.
That said, the source code is augmented with some type of markup that will be
replaced during the generation cycle with actual production code. The output file has
all of the original code, but the special markup has been replaced with production
code. This output file is then used for compilation to build the actual product.
4.2.1
Uses and examples
Among the many possible uses for inline-code expansion are:
• Embedding SQL in implementation files
• Embedding performance-critical assembler sections
• Embedding mathematical equations, which are then implemented by the generator
The decision of when to use an inline-code expander versus object-oriented or func-
tional library techniques can be critical. C++ has support for templating and inline
expansion within the language. You should look to these tools before contemplating the
building of a new language style based on inline-code expansion.
One important reason to avoid inline-code expansion is that the technique can
make debugging difficult because you are debugging against the output of the gener-
ator and not the original source code. Therefore, the choice to use inline code expan-
sion should be made with great regard for the both the positives and the negatives
associated with using this technique. The technique has been used successfully in
products such as Pro*C and SQLJ, which embed SQL in C and Java respectively, but
there are issues with debugging the resulting code.
Figure 4.11 depicts the input and output flow for the inline-code expansion model.
Source Code
Inline-Code
Expander
Output Source Code
Compiler
Executable
Figure 4.11
The input and output flow for an 
inline-code expansion generator
80
CHAPTER 4
B
UILDING
SIMPLE
GENERATORS
The code expander reads the input source code file, replaces any comments, and
creates an output file with the resulting code. The output code is fed to the compiler
and is used directly as part of the production application.
Let’s take a look at an example. This inline-code expander will take strings marked
in brackets and implement them with printf. The input filename is test.cx; the out-
put filename is test.c. Here’s our test input file:
int main( int argc, char *argv[] )
{
<Hello World>
return 0;
}
Our input file specifies that the "Hello World" string should be printed to stan-
dard output. The input file is fed to the generator, which outputs the following:
int main( int argc, char *argv[] )
{
printf("Hello World");
return 0;
}
As you can see, the "Hello World" string has been wrapped in a call to printf to
send it to the standard output. While this example is not particularly useful on its own,
it demonstrates the simplest form of the inline-code expansion technique.
The Ruby code that implements this generator is shown in listing 4.12.
unless ARGV[0]
print "ilce1 usage: ilce1 file.cx\n"
exit
end
fh = File.open( ARGV[0] )                           
text = fh.read()                                    
fh.close                                            
text.gsub!( /<(.*?)>/ ) { "printf(\"#{$1}\");" }    
new_file_name = ARGV[0]
new_file_name.gsub!( /[.]cx$/, ".c" )               
print "Creating #{new_file_name}\n"                 
File.open( new_file_name, "w" ).write( text )       
q
The regular expression substitution routine replaces every occurrence of <text> with
printf("text");. The gsub! method finds all of the occurrences of the regular
expression within the string. It then invokes the block on each occurrence and replaces
Listing 4.12 2 Listing 4.12 Inline-code expander: Printf maker
Creates the 
new file
Reads 
the file
Builds the new filename
w
Replaces <text> items
q
T
HE
INLINE
-
CODE
EXPANSION
GENERATOR
MODEL
81
the occurrence with the result of the block. The regular expression is shown in
exploded form in figure 4.12.
The < and > characters in the regular expression need to match exactly. In between
the two you can place any sequence of characters. In practice, you may want to tighten
up the expression to avoid grabbing legitimate C code and regarding it as an expression.
w
This regular expression substitution replaces the.cx and the end of the filename
with.c. Figure 4.13 describes the regular expression. The [.] matches an actual
period, the cx matches the string "cx", and the end of the string is marked by $. This
expression will match any .cx at the end of a string or, in this case, a filename.
4.2.2
Developing the generator
Figure 4.14 shows a sample process for developing an inline-code expansion code generator.
Let’s examine these steps in greater detail:
• Build the test code—First, build the code you would like the generator to create.
That way, you can compile it and see if it works for you.
• Design the generator—Next, design the input file format for the generator. You
should also sketch out the flow of your generator.
• Develop the input parser—The first step in building the generator is to read the
input file and extract any information from it that is not related to the code
<(.*?)>
Thestarting'<'
Anytypeoftextgroupedtogetheras
$1
Theending'>'
Figure 4.12
The regular expression for 
finding the printable text
[.]cx$
Theendof
theline
The'.'
character
Thetext'cx'
Figure 4.13
The regular expression 
for finding 
.cx
BuildTestCode
DesignGenerator
DevelopTemplates
FromTestCode
DevelopInputParser
DevelopOutputCode
Builder
DevelopCode
Replacer
Figure 4.14
The design and implementation steps for 
developing an inline-code expansion generator
Documents you may be interested
Documents you may be interested