← Back to projects

Compilers and parsing

A small recursive descent parser written in C

The parser reads a stream of numeric tokens and checks a simplified Pascal style program. Each grammar rule lives in a small C function, so the call structure mirrors the language: factors build terms, terms build expressions, and expressions feed statements.

CRecursive descentGrammarToken stream

Parser structure

The functions follow operator precedence

Numeric tokens
Program driver
Statements
Expression rules
Success or failure

FACTOR

Accepts an identifier, integer, or parenthesized expression.

TERM

Consumes factors joined by multiplication or division.

EXP

Consumes terms joined by addition or subtraction.

Accepted language

A compact grammar for coursework

A program begins with program, an identifier, a variable declaration, and begin. Its body can contain assignments, read, write, and simple for loops. The parser advances one lookahead token and stops on the first rule that cannot be satisfied.

program  → PROGRAM ID VAR idlist : INTEGER BEGIN statements END
idlist   → ID { , ID }
assign   → ID := expression
expr     → term { ( + | - ) term }
term     → factor { ( * | / ) factor }
factor   → ID | INT | ( expression )

Implementation

One source file per grammar routine

File Role
main.c Reads tokens and validates the program level sequence and statements
idlist.c Parses comma separated identifiers
factor.c, term.c, exp.c Apply arithmetic precedence
assign.c, read.c Parse statement forms
tokens.h Maps token names to the numeric input representation

Result

The parser returns one binary result

The program prints success when the token stream matches the expected grammar. Any mismatch follows the failure path, prints failed, and returns a nonzero exit status.

make
./parser

# enter token numbers defined in tokens.h

Scope

This project implements syntax recognition only. Tokenization, source locations, recovery after an error, and an abstract syntax tree are outside its coursework scope.