Macro Processor
Macro Processor
Chapter-1
Introduction
1.1. Problem Definition
Processing of source code for a compiler requires many tasks before actual
compilation of the program. Most of theses tasks require refinement of code for the machine
to understand. Programmers may write code to the best possible extent of their
understanding and simplicity. Therefore, thisrequires a translation to more extensive code that
the compiler can understand. Some of the problems faced by programmers in writing
extensive code are explained indetail in the next few paragraphs.
2014-15
Page 1
Macro Processor
the functions carry small amounts of code in them. Therefore, functions should not be usedto
hold replacement code, but to hold relevant code that needs to be called only when required.
2014-15
Page 2
Macro Processor
The macro name must be a valid, unique symbol. It cannot be redefined later. Keywords
cannot be used as macro names. The macro body may comprise any number of lines. Body
lines may be all kinds of assembler instructions, pseudo instructions, controls, meta
instructions, macro calls and even further macro definitions.
The macro body and the whole macro definition is terminated with the ENDM instruction.
Macros must be defined, before they can be called. Forward references to macros are not
allowed. Once defined, a macro can be called by its name in the subsequent program as often
as desired. Whenever a macro is called, the macro body will be "inserted" into the program
and then assembled as normal source lines. This process is called macro expansion.
2014-15
Page 3
Macro Processor
3. single printable characters, preceded by '!' as an escape character
4. character sequences, enclosed in literal brackets < ... >, which may be arbitrary
sequences of valid macro arguments (types 1. - 4.), blanks, commas and semicolons
5. arbitrary sequences of valid macro arguments (types 1. - 4.)
6. expressions preceded by a '%' character
Macro
commentary
Literal operator
<>
Literal brackets
Evaluation
2014-15
Page 4
Macro Processor
on pass 1.
The '&' character separates parameter names (local symbols)
from surrounding text. Outside quoted strings and commentary
it serves only as a general separation character. This applies
always when a local symbol directly precedes or follows
another alphanumeric string. Inside quoted strings and
&
Substitution
2014-15
Page 5
Macro Processor
Chapter-2
Theory and Concepts of Macro Processor
2014-15
Page 6
Macro Processor
2.1 Introduction
Macro processor replaces each macro instruction with the corresponding group of
source language statements (expanding). Normally, it performs no analysis of the text it
handles. The design of a macro processor generally is machine independent.In this project,a
macro processor which analyses the given macro lines into tokens of label,opcode,operand
and stored seperately.It is processed to produce the expanded output.Our approach is to build
a single pass macro processor.
2014-15
Page 7
Macro Processor
1) Two
pass Macroprocessor.
2) One pass Macroprocessor
.
Flowchart:
2014-15
Page 8
Macro Processor
Pass 1
MDTC<-1
Rea
M
MNTC<-1
d
A
next
C
Writ
sour
R
e
E
ce
O
cop
N
card
ps
y of
Rea
D
Enter
eu
sour
d
ps
macro
do
ce
next
eu
name
Sub
Rea
card
sour
do
Go
and
stitu
d
op
ce
to
current
te
next
?
card
op
Pas
value of
inde
sour
s?2
MDTC in
x
ce
MNT
nota
MNTC <- MNTC + 1
card
entry
tion
M
Enter
Prepare argument
number list array
Enter line
for
Einto MDT
macro
MNTC
argu
N
name
MDTC <- MDTC + 1
men
D
card into
MDTC <- MDTC + 1
ts
ps
MDT
eu
do
op
?
Data Structure
DEFTAB (definition table)
1) To Stores the macro definition includes prototype and macro body.
2) Comment lines are omitted.
3) References to the macro instruction parameters are converted to a positional
notation for efficiency in substituting arguments.
2014-15
Page 9
Macro Processor
NAMTAB
1) Stores macro names.
2) Serves as an index to DEFTABby pointing to the beginning and the end of
the macro definition (DEFTAB)
ARGTAB(argument Table)
1) Stores the arguments of macro invocation.
2) As the macro is expanded, arguments from ARGTAB are substituted for the
corresponding parameters in the macro body.
Chapter-3
Software Requirements Specification
Dept of ISE, RVCE
2014-15
Page 10
Macro Processor
Chapter-4
2014-15
Page 11
Macro Processor
The design of macro processor doesnt depend on the architecture of the machine.
We will be studying some extended feature for this macro processor. These features are:
Concatenation of Macro Parameters
Generation of unique labels
Conditional Macro Expansion
Keyword Macro Parameters
2014-15
Page 12
Macro Processor
By the time the program is assembled, all such decisions havebeen made. There is only one
sequence of source statements during program execution.
Keyword parameters
Each argument value is written with a keyword that names the corresponding parameter.
Arguments may appear in any order. Null arguments no longer need to be used.It is easier to
read and much less error-prone than the positional method.
4.5 Language
C programming language is used.
2014-15
Page 13
Macro Processor
B to be the assembly language for some machine, then it might be possible for a macro
processor to perform the compilation from A to B.
Level 1 :
Here, source code is broken into tokens and passed into identify module.It checks whether
the opcode is Macro or it is defined in the code.and passed to substitute module,where it
expands or replaces macro as identified by previous module.
Level 2:
2014-15
Page 14
Macro Processor
Source code is processed into word scanner,each word or a macro line is checked by
processline.It searches NAMTAB for opcode,or MACRO opcode else expand it.Define enters
defination and prototype into DEFTAB and NAMTAB respectively.GETLINE substitute
actual arguments with formal parameters.and EXPAND produces expanded output.
Chapter-5
DETAILED DESIGN
This chapter discuss about the data structure and control flow in the software with much more
details about software modules by clarifying the details about each function with
functionality, purpose, input and output. The decision taken are based on certain design
2014-15
Page 15
Macro Processor
considerations, constraints and dependencies which will affect the subsequent functioning of
the product.
2014-15
Page 16
Macro Processor
Functionality: This module is responsible to scan the macro line and process it.
Flow Chart: The Flow Chart for the search module is shown in figure 0.1.1
Input: Tokens.
Flow Chart: The Flow Chart for the search module is shown in figure 0.1.2
2014-15
Page 17
Macro Processor
procedure PROCESSLINE
begin
search NAMTAB for OPCODE
if found then
EXPAND
else if OPCODE = MACRO then
DEFINE
Else write source line to expanded file
End (PROCESSLINE)
5.3.3 Define:
.
Functionality: Enters the Macro name into NAMTAB and prototype into DEFTAB,
comment lines are neglected. Care is taken if a Macro is called within a Macro. Hence
prototype is stored in NAMTAB with beginning and end pointer
Flow Chart: The Flow Chart for the search module is shown in figure 0.1.3
2014-15
Page 18
Macro Processor
enter line into DEFTAB
if OPCODE = MACRO
LEVEL := LEVEL + 1
else if OPCODE =: MEND then
LEVEL := LEVEL - 1
end (if not comment)
end ( while )
store in NAMTAB pointers to beginning and end of definition
end (DEFINE)
5.3.4 Getline:
Functionality: If Expanding is true, line is taken from DEFTAB and arguments are
substituted for positional notation.
Flow Chart: The Flow Chart for the search module is shown in figure 0.2.1
Dependency: It depends
arguments.
Algorithm:
procedure GETLINE
begin
if EXPANDING then
begin
get next line of macro definition from DEFTAB
substitute arguments from ARGTAB for positional notation
end ( if )
else
read next line from input file
end {GETLINE}
5.3.5 Expand:
Dept of ISE, RVCE
2014-15
Page 19
Macro Processor
Flow Chart: The Flow Chart for the search module is shown in figure 0.2.2
DEFTAB:
Description: It is used to Stores the macro definition includes prototype and macro
body. Comment lines are omitted.References to the macro instruction parameters are
converted to a positional notation for efficiency in substituting arguments.
NAMTAB:
Dept of ISE, RVCE
2014-15
Page 20
Macro Processor
Description: Stores macro names, Serves as an index to DEFTAB by pointing to the
beginning and the end of the macro definition (DEFTAB)
ARGTAB:
Description:Stores the arguments of macro invocation. As the macro is expanded,
arguments from ARGTAB are substituted for the corresponding parameters in the macro
body.
Expanded code:
Description:Data stored after processed by macro processor. The code is brought to
the state to be processed by compiler or assembler.
Chapter-6
Dept of ISE, RVCE
2014-15
Page 21
Macro Processor
IMPLEMENTATION
6.1 Algorithm
The following functionalities are implemented in our C code for macro processor:
MACROPROCESSOR
EXPANDING=FALSE.
Read each line and call GETLINE() and PROCESSLINE() until END encounters.
PROCESSLINE ( )
If OPCODE is a macroname then EXPAND ( ).
Else if OPCODE is MACRO ,then DEFINE ( ).
Else write line to expanded file as such.
DEFINE( )
Enter Macro name into NMATAB.
Enter macro prototype into DEFTAB.
Set LEVEL=1.
Substitute parameters with positional notations and enter to DEFTAB.
If OPCODE=MACRO, LEVEL++;
If OPCODE=MEND, LEVEL--;
Continue this until LEVEL=0
Store beginning and end of definition as pointers within NAMTAB
EXPAND ( )
EXPANDING = TRUE
Set up arguments from macro invocation in ARGTAB.
Write macro invocation statement to expanded file as a comment line.
Call GETLINE() and PROCESSLINE() till macro definition ends.
Dept of ISE, RVCE
2014-15
Page 22
Macro Processor
Set EXPANDING=FALSE.
GETLINE ( )
If EXPANDING is TRUE, read from DEFTAB (data structure where macro body is
stored) and substitute arguments for positional notations.
If EXPANDING is FALSE , read next line from input file.
UINQUE LABEL GENERATION
a. Labels in the macro body may cause duplicate labels problem if the macro is
invocated and expanded multiple times.
b. Use of relative addressing at the source statement level is very inconvenient, errorprone,
and difficult to read.
c. It is highly desirable to
- let the programmer use label in the macro body
a. Labels used within the macro body begin with $.
- let the macro processor generate unique labels for each macro invocation and expansion.
b. During macro expansion, the $ will be replaced with $xx, where xx is a twocharacter
alphanumeric counter of the number of macro instructions expanded.
c. XX=AA, AB, AC,.
2014-15
Page 23
Macro Processor
General purpose programming language: C can be used to implement any kind of
applications such as math s oriented, graphics, business oriented applications.
Portability:
(unix,dos,windows).
Powerful programming language: C is very efficient and powerful programming
language, it is best use d for data structures and designing system software.
C is case sensitive language.
Chapter-7
SOFTWARE TESTING
Dept of ISE, RVCE
2014-15
Page 24
Macro Processor
At testing stage of this project, defects or errors were discovered by testing individual
program components. Testing was focused on establishing functional requirements and on
system behavior in given scenario. The test cases are selected to ensure that the system
behavior can be examined in all possible combinations of conditions.
Accordingly, expected behavior of the system under different conditions is given. Therefore
test cases are selected which have inputs and the outputs are as expected.
2014-15
Page 25
Macro Processor
The second level of testing is called integration testing. Integration testing deals with finding
defects in the way individual parts work together. In this, many unit tested modules are
combined into subsystems, which are then tested. The goal here is to see if all the modules
can be integrated properly.
2014-15
Page 26
Macro Processor
Sample Input :
Expected output :
Actual output :
Remarks :
Test case 2 as shown in table 7.2 searches the labels in the program. And finally it generates
the unique labels in the out file
Table 7.3 nested macro unit test case 3
3
Nested macro
Nested macro
Program with nested macros.
Program with nested macros expanded.
Program with nested macros expanded.
Test successful.
Test case 3 as shown in table 7.3 tests the nested macros in the program and expands them
accordingly and the output program with macros expanded is obtained.
Table 7.4 Time to expand a macro unit test case 4
4
Time to expand a macro in program
Macro processor
Program with macro
Program with macro, is expanded in 0.019 seconds.
Program with macro, is expanded in 0.019 seconds.
Test successful.
Test case 4 as shown in table 7.4 checks the total time required to expand the macro by macro
processor.Timer is started, before expanding the macro starts and timer is stopped after the
macro processor has expanded. The duration is calculated and displayed as output on the
screen. Sample output test is shown in above table.
7.7 Summary
Implementation describes the important decisions taken for the development of the project.
Programming language selection which can help in the designing of the project efficiently is
Dept of ISE, RVCE
2014-15
Page 27
Macro Processor
chosen. The platform selection is described based on the requirement of the project. The
coding convention used in the project is explained in detail. Software testing deals with the
testing of each module to meet the functional requirements. Various stages of testing are
included. The test cases to test and their respective outcomes are tabulated.
CHAPTER 8
RESULTS, DISCUSSION AND INFERENCE
8.1 Advantages and Disadvantages
The following are the major advantages of the project
Effectively replaces code that was meant for replacement with the macro.
Used concepts such as file pointers, structures to carry out its tasks
2014-15
Page 28
Macro Processor
Highlights errors caused by macros that the programmer can rectify before the
code is sent for compilation rather than to be intimated of errors during
compilation
Produces the output file, even if there are errors or warnings in the input file.
Maintains a separate input file and a separate output file for data verification
and rectification.
Maintains macro names and their definitions in structures, thereby reducing the
amount of resources involved with character arrays and is useful for debugging
purposes.
Tabs and whitespaces and original contents of the input file are maintained as
they are even in the final source code file.
2014-15
Page 29
Macro Processor
Inclusion of a compiler
Steps can be taken to develop an IDE (Integrated Development Environment), so that
the output cpp file can be directly compiled and the results caused due to macro
expansions can be taken care of. However, the development of an IDE would require
also the development of an editor, a parser, linker and other systems software concepts
that are well beyond the boundaries of a simple macro processor. However, with the
combination of a compiler, the use of macros can be fully justified.
User-defined macros
User-defined macros can be setup to help programmers work with arrays and files
better. These macros can be used to perform regular tasks such as arranging elements
in ascending or descending order, or to open files with a given filename and file mode.
These specifics can be applied with more input from the programmer as to how he
would like to lessen the amount of typing and to help increase readability.
REFERENCES
1) ANDREW S. TANENBAUM, A General-Purpose Macro Processor as a Poor Man's
Compiler-Compiler, IEEE TRANSACTIONS ON SOFTWARE ENGINEERING,
VOL. SE-2, NO. 2, JUNE 1976
2) P. J. Brown, "The ML/I macro processor," Commun. Ass. Comput. Mach., vol. 10, pp.
618-623, Oct. 1967.
2014-15
Page 30
Macro Processor
3) W. Wulf, D. Russell, and A. Habermann, "BLISS: A language for systems
programming," Commun. Ass. Comput. Mach., vol.14, pp. 780-790, Dec. 1971.
4) P. J. Brown, "Macro processors and software implementation," Comput. J., vol. 12,
pp. 327-331, Nov. 1969.
5)
Marshall, Martin (April 29, 1991). "Macro Assembler Update Adds High-Level
Features". InfoWorld 13 (17): p. 21. ISSN 0199-6649.
Appendices
Appendix A
Source code
Code.c
#include<stdio.h>
#include<string.h>
#include<stddef.h>.
Dept of ISE, RVCE
2014-15
Page 31
Macro Processor
#include str_rep.h
FILE *input_f,*output_f;
int main ()
{
int test;
int counter=99;
int j,check_endof_macro;
check_endof_macro=1;
j=0;
input_f = fopen("input.txt","r");
output_f = fopen("expanded.txt","w");
while(1){
j++;
if( feof(input_f) ){break ;
}
fscanf(input_f,"%s %s %s",label,opcode,operand);
counter=search(opcode);
if(counter!=99)
{
write_to_file(1,counter);
printf("\nok\n");
continue;
}
write_to_file(0,0);
if(strcmp(opcode,"MACRO")==0){
strcat(arg[c_d], operand);
strcat(name[c_d], label);
check_endof_macro=1;
while(check_endof_macro)
{
fscanf(input_f,"%s %s %s",label,opcode,operand);
counter=search(opcode);
Dept of ISE, RVCE
2014-15
Page 32
Macro Processor
if(counter!=99)
{
nestmacro(counter,c_d);
printf("\nok\n");
continue;
}
write_to_file(0,0);
check_endof_macro=strcmp(opcode,"MEND");
if(check_endof_macro!=0)
{
write_to_deftab(c_d);
}
}
c_d++;
}
}
test=search("RBUFF");
fclose(input_f);
}
int countdef=0;
int c,expnd=0;
char label[20],opcode[20],operand[20];
char
name[10][10]={"","","","","","","","","",""},arg[10]
[100]={"","","","","","","","","",""},def[30][4096]={"","","","","","","","","",""};
char unique_Label='A';
int search(char *macro_name)
{
int i;
2014-15
Page 33
Macro Processor
for(i=0;i<c_d;i++)
{
if(strcmp(macro_name,name[i])==0)
{
//
printf("\nccc%d\n",i);
return i;
}
}
return 99;
}
char *split_Argtab(char str[128],int count_Split)
{
char * pch=" ";
// printf ("Splitting string \"%s\" into tokens:\n",str);
if(count_Split>0)
{
pch = strtok (str,",");
while (pch != NULL && count_Split>1)
{
pch = strtok (NULL, ",");
count_Split--;
}
}
//printf("%s\n",pch );
return pch;
}
/*
int count_Argtab(char a[30])
{
Dept of ISE, RVCE
2014-15
Page 34
Macro Processor
int count_arg=0,i=0;
/*char *t;
t=st;
//*s='\0';
printf("%s\n",t);
while(*t!='a')
{
if(*t==',')
count_arg++;
printf("check\n");
t++;
}*/
/*
printf("%s\n",a );
int len=strlen(a)-1;
printf("%c\n",a[0] );
while(i!=3)
{
if(!strcmp(',',a[i]))
count_arg++;
i++;
}
return count_arg;
}*/
int write_to_file(check_Expand,counter)
{
char operands[10][128]={"","","","","","","","","",""};
char arg_operands[10][128]={"","","","","","","","","",""};
char * pch;
char *split_opnd=" ";
char *token;
int icount=0,len=0,ii=0,count_arg=0,i,count_Split;
char *opnd_Replace;
Dept of ISE, RVCE
2014-15
Page 35
Macro Processor
char dummy[128]={""};
char def_buffer[4096];
if(check_Expand==1)
{
fprintf(output_f, ";");
fprintf(output_f, label);
fprintf(output_f, " ");
fprintf(output_f, opcode);
fprintf(output_f, " ");
fprintf(output_f, operand);
fprintf(output_f, "\n");
//printf("%s",split_Argtab(arg[counter],2));
//Splitting Operand
len=strlen(operand)-1;
while(ii!=len)
{
if(operand[ii]==',')
count_arg++;
ii++;
}
/*for ( i = 0; i <count_arg ; i++)
{
count_Split=i+1;
if(count_Split>0)
{
split_opnd = strtok (operand,",");
while (split_opnd != NULL && count_Split>1)
{
split_opnd = strtok (NULL, ",");
count_Split--;
}
Dept of ISE, RVCE
2014-15
Page 36
Macro Processor
};
strcat(operands[i],split_opnd);
}*/
for (i =0; i <=count_arg ; i++)
{
/* code */
strcpy(dummy,operand);
//printf("#%s\n\n",split_Argtab(dummy,i+1));
strcat(operands[i],split_Argtab(dummy,i+1));
}
//Splitted Opnd
count_arg=0;
ii=0;
//Splitting Arguments
len=strlen(arg[counter])-1;
while(ii!=len)
{
if(arg[counter][ii]==',')
count_arg++;
ii++;
}
for (i =0; i <=count_arg ; i++)
{
/* code */
strcpy(dummy,arg[counter]);
//printf("#%s\n\n",split_Argtab(dummy,i+1));
strcat(arg_operands[i],split_Argtab(dummy,i+1));
}
//Splitting arg done
Dept of ISE, RVCE
2014-15
Page 37
Macro Processor
//Copying argtab
i=0;
for (i =0; i <=count_arg ; i++)
{
/* code */
//printf("%s\n",arg_operands[0] );
//opnd_Replace = strstr (def[counter],arg_operands[0] );
//strncpy (opnd_Replace,"sam",3);
strcat(def_buffer,replace_str2(def[counter],arg_operands[i],operands[i]));
def[counter][0]='\0';
strcat(def[counter],def_buffer);
def_buffer[0]='\0';
printf("%s\n",def[counter] );
}
//copying done
fprintf(output_f, def[counter]);
count_arg=0;//to count no. of again for different macro
return 2;
}
fprintf(output_f, label);
fprintf(output_f, " ");
fprintf(output_f, opcode);
fprintf(output_f, " ");
fprintf(output_f, operand);
fprintf(output_f, "\n");
return 1;
}
int nestmacro(int counter,int macroCounter)
{
strcat( def[macroCounter],def[counter]);
}
int write_to_deftab(int d_c)
Dept of ISE, RVCE
2014-15
Page 38
Macro Processor
{
char label[40]=" ";
if(strcmp("NULL",label)!=0)
{
//strcat(label,'$');
label[0]='$';
label[1]=unique_Label;
unique_Label = unique_Label + 1;
strcat(label,label);
strcat(def[d_c], label);
}
else
{
strcat(def[d_c], label);
}
strcat(def[d_c], " ");
strcat(def[d_c], opcode);
strcat(def[d_c], " ");
strcat(def[d_c], operand);
strcat(def[d_c], "
");
strcat(def[d_c], "\n");
}
str_rep.h
char *replace_str2(const char *str, const char *old, const char *new)
{
char *ret, *r;
const char *p, *q;
size_t oldlen = strlen(old);
size_t count, retlen, newlen = strlen(new);
int samesize = (oldlen == newlen);
if (!samesize) {
Dept of ISE, RVCE
2014-15
Page 39
Macro Processor
for (count = 0, p = str; (q = strstr(p, old)) != NULL; p = q + oldlen)
count++;
retlen = p - str + strlen(p) + count * (newlen - oldlen);
} else
retlen = strlen(str);
if ((ret = malloc(retlen + 1)) == NULL)
return NULL;
r = ret, p = str;
while (1) {
if (!samesize && !count--)
break;
if ((q = strstr(p, old)) == NULL)
break;
ptrdiff_t l = q - p;
memcpy(r, p, l);
r += l;
memcpy(r, new, newlen);
r += newlen;
p = q + oldlen;
}
strcpy(r, p);
return ret;
}
2014-15
Page 40
Macro Processor
APPENDIX B
Output Screenshot
Input file
2014-15
Page 41
Macro Processor
2014-15
Page 42
Macro Processor
Output file
2014-15
Page 43
Macro Processor
2014-15
Page 44