Category Archives: SPCC

Implementation of Bottom-Up (Shift-Reduce) Parsing in C++

Bottom-up parsing is a strategy used by compilers to analyse source code by building the parse tree from the leaves (terminal symbols) up to the root (start symbol). The most common bottom-up technique is shift-reduce parsing, which uses a stack and a set of production rules. At each step the parser either shifts the next input symbol onto the stack, or reduces the top of the stack by replacing a substring that matches the right-hand side of a production rule with the corresponding left-hand side symbol.

This C++ program implements a simple shift-reduce parser. It reads a set of production rules and an input string from the user, then processes the string step by step, displaying the stack contents, remaining input, and the action taken (Shifted or Reduced) at every stage.

Continue reading Implementation of Bottom-Up (Shift-Reduce) Parsing in C++

Implementing Lexical Analyser in C++

Lexical analysis (also called scanning or tokenisation) is the very first phase of a compiler. The lexical analyser reads the raw source text character by character and groups characters into meaningful units called tokens. Each token belongs to a category: an identifier (variable or function name), a literal (numeric constant), or a terminal (operator or punctuation symbol found in a predefined database file).

This C++ program reads an expression string (terminated by $) from the user, classifies each character, and builds a Uniform Symbol Table (UST) that records every token together with its type (LIT, IDN, or TER) and a pointer (sequential index within its type). The results are written to four files and then displayed on the console.

Required file: Before running the program you must create D:andb.txt containing all operator/punctuation characters that should be recognised as terminals (e.g. =+-*/()/), one or more per line.

Continue reading Implementing Lexical Analyser in C++

Implementing Code Generator in C++

Code generation is the final back-end phase of a compiler. It takes the intermediate representation (IR) of the program — typically a sequence of three-address instructions — and translates each one into the equivalent target machine instructions. For a register-based architecture like the 8086, this means emitting MOV, ADD, SUB, MUL, DIV, and assignment instructions that use the AX and BX registers.

This C++ program reads three-address IR instructions from an input file (AIP.TXT), generates the corresponding 8086-style assembly code, and writes it to an output file (ANOP.TXT). Each IR instruction has the form:

operator  operand1  operand2  result
Continue reading Implementing Code Generator in C++

Implementing Absolute Loader in C++

A loader is a system program responsible for placing a program into memory so it can be executed. An absolute loader is the simplest type: it loads a program at a fixed, pre-determined memory address (the starting address is embedded in the object file itself and cannot be changed). This contrasts with a relocating loader, which can place the program anywhere in memory and patches all address-dependent instructions accordingly.

This C++ program simulates an absolute loader. You provide a starting address and the values to be placed at consecutive bytes, and the program then lets you query what the value at any relocation address (offset from the starting address) would be — mimicking the act of loading and then reading back memory.

Continue reading Implementing Absolute Loader in C++

Implementing Macro Processor in C

A macro processor is a system program that expands macros in a source file before the code is assembled or compiled. A macro is a named block of assembly statements; every time its name appears in the program the processor substitutes the full block in place of the call. This eliminates repetition and makes large assembly programs easier to maintain.

This C implementation reads an assembly program from MACIN.TXT, detects MACRO / MEND delimiters to populate a Macro Definition Table (MDT), and then expands every macro call by inline-substituting the stored body. The expanded output is written to MACOUT.TXT and the raw MDT is saved to MDT.TXT.

Continue reading Implementing Macro Processor in C

Implementing Multi-pass Assembler in C

An assembler is a system software tool that translates an assembly language program (ALP) into machine code. A multi-pass assembler does this translation in two distinct passes over the source program. In Pass 1, it scans the ALP to build a Symbol Table (ST) that maps all labels and symbols to their memory addresses. In Pass 2, it uses the symbol table along with a Machine Opcode Table (MOT) and a Pseudo Opcode Table (POT) to generate the final object code.

This C implementation reads the assembly program from alp.txt, the machine opcode table from mot.txt, and the pseudo opcode table from pot.txt. The generated object code is written to OUTPUTNEW.txt and the symbol table is saved to SymT.txt.

Continue reading Implementing Multi-pass Assembler in C