Skip to content

This repository is a simplified Pascal compiler in C++ I did during my bachelor's degree at Avignon Université.

License

Notifications You must be signed in to change notification settings

JustFallBack/pascal-compiler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

82 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Pascal compiler

A simple Pascal compiler.
From : Pascal-like imperative LL(k) langage
To : 64 bit 80x86 assembly langage (AT&T)

This project has been done for academical purposes.
This compiler is very simple, some pascal features are not handled
The set of instructions used for the assembly code work with 64 bit 80x86 assembly langage.

This project was developped on Ubuntu 22.04.

Build the compiler :

You can test different files that are in pascal_test folder.
For exemple :

make VERSION=All

will compile the program using testAll.p file.

For additional help, type the following command :

make
make help

Finally, you can execute the programm :

./test

You can have a look at the produced assembly code in test.s.

Download the repository :

git clone git@github.com:JustFallBack/pascal-compiler.git

Grammar

-  Statement := AssignementStatement | IfStatement | WhileStatement | ForStatement | BlockStatement | DisplayStatement | CaseStatement
-  IfStatement := "IF" Expression "THEN" Statement [ "ELSE" Statement ]
-  WhileStatement := "WHILE" Expression "DO" Statement
-  ForStatement := "FOR" AssignementStatement ( "TO" | "DOWNTO" ) Expression "DO" Statement
-  BlockStatement := "BEGIN" Statement { ";" Statement } "END"
-  DisplayStatement := "DISPLAY" Expression
-  CaseStatement := "CASE" Expression "OF" CaseListElement {";" CaseListElement} ["ELSE" Statement] "END"
-  CaseListElement := CaseLabel ":" Statement
-  CaseLabel := Factor { "," Factor }

-  Program := [VarDeclarationPart] StatementPart
-  VarDeclarationPart := "VAR" VarDeclaration {";" VarDeclaration} "."
-  VarDeclaration := Identifer {"," Identifier} ":" Type
-  StatementPart := Statement {";" Statement} "."
-  Statement := AssignementStatement
-  AssignementStatement := Letter "=" Expression

-  Expression := SimpleExpression [RelationalOperator SimpleExpression]
-  SimpleExpression := Term {AdditiveOperator Term}
-  Term := Factor {MultiplicativeOperator Factor}
-  Factor := "(" Expression ")" | Number | Identifier | CharConst | BoolConst
-  Identifier := Letter{Letter|Digit}
-  Number := {digit}+(\.{digit}+)?
-  CharConst := "'" Letter "'"
-  BoolConst := "TRUE" | "FALSE"

-  AdditiveOperator := "+" | "-" | "||"
-  MultiplicativeOperator := "*" | "/" | "%" | "&&"
-  RelationalOperator := "==" | "!=" | "<" | ">" | "<=" | ">="  
-  Digit := "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
-  Letter := "a"|...|"z"
-  Type := "INTEGER" | "BOOLEAN" | "DOUBLE" | "CHAR"

Type handled

  • INTEGER
  • BOOLEAN
  • DOUBLE
  • CHAR

Negative INTEGER and DOUBLE are not supported.

Debug the executable with ddd :

ddd ./test

Debug the executable manually with gdb

gdb ./test

Create a break point where gdb stops at specified label (for exemple, break main makes gdb stops at the start of the assembly code).
You can make break point at a specific line (break 26 to make gdb stops at 26th line) :

(gdb) break label
(gdb) break line

Clear specified break point :

(gdb) clear label
(gdb) clear line

Run the debug :

(gdb) run

Next step :

(gdb) step
(gdb) s

Continue to next break point :

(gdb) continue
(gdb) c

Information on CaseStatement :

Here are a few example of what CaseStatement can handle in this version.

WARNING

This version does not handle repetition.
For example, the following code won't alert that there is the possibilty of e being 1 multiples time.
It will execute the statement associated to the first occurence (here the first line) and will skip every other statements in the CaseStatement (like if there was a break instruction after each Statement).

VAR e : INTEGER.

CASE e OF
1       : Statement;
1,2,3   : Statement;  
1..5    : Statement  
END.

CaseStatement with INTEGER :

VAR e,a : INTEGER.

a:=86;

CASE e OF
1       : Statement;  // if e is 1
6,7,12  : Statement;  // if e is either 6,7 or 12
a,999   : Statement   // if e is either equal to a (here, 86) or 999
ELSE
    Statement         // if e is not equal to any of the specified value
END.

CaseStatement with BOOLEAN :

VAR flag : BOOLEAN;
    a    : INTEGER.

flag:=TRUE;
a:=8;

CASE flag OF
TRUE   : Statement; // if flag is TRUE
FALSE  : Statement  // if flag is FALSE
END

// previous CASE is equivalent to ;
CASE flag OF
TRUE   : Statement  // if flag is TRUE
ELSE
    Statement       // if flag is not TRUE
END

NOTE : it is possible to put a comma between boolean values (TRUE or FALSE).

CaseStatement with DOUBLE :

VAR     a,d : DOUBLE;

a := 15.0/2.0;
d := 4.2*2.0;

CASE a OF
1.0      : Statement;  // if a is 1.0
2.0,7.54 : Statement;  // if a is either 2.0 or 7.54
d, 8.0   : Statement   // if a is either equal to d or 8.0
ELSE
    Statement          // if a is not equal to any of the specified value
END.

CaseStatement with CHAR :

WARNING

There must be a whitespace between the , (COMMA) and the ' (single quote).
It is due to the way lexer handles tokens.

VAR e,d : CHAR.

d := '$';

CASE e OF
'a'         : Statement;  // if e is 'a'
'b', 'c'    : Statement;  // if e is either 'b' or 'c'
d, 'd'      : Statement   // if e is either equal to d or is 'd'
ELSE
    Statement             // if e is not equal to any of the specified value
END.

About

This repository is a simplified Pascal compiler in C++ I did during my bachelor's degree at Avignon Université.

Topics

Resources

License

Stars

Watchers

Forks