Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/raphaelpour/pl0
PL/0 to custom vm compiler. My solution for the university module 'compiler constructions'.
https://github.com/raphaelpour/pl0
Last synced: 18 days ago
JSON representation
PL/0 to custom vm compiler. My solution for the university module 'compiler constructions'.
- Host: GitHub
- URL: https://github.com/raphaelpour/pl0
- Owner: RaphaelPour
- Created: 2022-02-02T10:51:06.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2022-02-02T11:07:16.000Z (almost 3 years ago)
- Last Synced: 2024-08-01T19:18:57.530Z (3 months ago)
- Language: Python
- Size: 225 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.MD
Awesome Lists containing this project
README
#PL/0 Compiler
This Python-based Compiler converts PL/0 source code into CL/0 virtual machine code. Both are educational languages with the aim to get faster to the real handwork of compiler-construction.
This project is the outcome of the Compilerconstruction module at the HTW Dresden.
## Usage
python3 cpl0.py [--ast]
The outcoming virtual machine codefile can be run with the vm of my supervising Professor which can be found here [here](http://www.informatik.htw-dresden.de/~beck/Compiler/bin/rlinux) (compiled for linux 32-bit). It can be used like ``./rlinux ``.
## PL0-Features
PL/0 provides a bunch of features such as:
* Arithmetic expressions
* I/O Operations including printing a value and receiving it as user input
* Conditions
* While-Loop
* Procedures/Constants/Variables with different scopesAdditional Features
* Output string
* Block comments
* For-Loop
* Procedures with Parameters
* Arrays
* Logical Expressions## Examples
### Hello World
~~~~
! "Hello World!".
~~~~### Arithmetic expressions
~~~~
!- 3+ (-4).
~~~~### I/O
~~~~
VAR input;
BEGIN
?input;
!input
END.
~~~~### If
~~~~
VAR a,b;
BEGIN
?a;
?b;
IF a = b THEN !0;
IF a # b THEN !1;
IF a >= b THEN !3;
IF a > b THEN !4;
IF a < b THEN !5;
IF a <= b THEN !6;IF ODD a THEN !7
END.
~~~~### If-Else
If-Else Odd-Number tester
~~~~
VAR input;
PROCEDURE main;
BEGIN
!" >>>>>>>>> ODD Tester >>>>>>>>>";
!"Input 0 to exit.";
!"Input Number:";
?input;
WHILE input # 0 DO
BEGIN
IF ODD input THEN !"ODD"
ELSE !"EVEN";
!"Input Number:";
?input
END
END;
CALL main.
~~~~Extended If-Else with a third case using Else-If.
~~~~
CONST pHNeutral=7;
VAR input;
PROCEDURE main;
BEGIN
!"Input pH Value:";
?input;
IF input = pHNeutral THEN !"Neutral"
ELSE IF input > pHNeutral THEN !"Alkaline"
ELSE !"Acid"
END;
CALL main.
~~~~### While-Loop
~~~~
VAR a, fak;
BEGIN
?a;
fak:=1;
WHILE a > 0 do
BEGIN
fak:= fak*a;
a:=a-1;
! a;
! fak
END
END .
~~~~### Define Procedures/ Constants/ Variables
~~~~
CONST a=5;
VAR b;
PROCEDURE main;
BEGIN
!b;
b := a;
!b
END;
CALL main.
~~~~### Procedures with parameters
~~~~
PROCEDURE f(x);
!x;
CALL f(7331).
~~~~Exponentiation programm using a self implemented pow function
~~~~
VAR result,i,a,b;
PROCEDURE pow(base,power);
BEGIN
result := 1;
FOR(i:=0;i= 0; i:=i-1)
FOR(j:=1; j <= i; j:=j+1)
IF x[j-1] > x[j] THEN
BEGIN
tmp := x[j-1];
x[j-1] := x[j];
x[j] := tmp
END;/* Display */
FOR(i:=0; i < 5; i:=i+1)
!x[i]
END.
~~~~### Recursion
~~~~
CONST a=5;
VAR b;
PROCEDURE sub;
BEGIN
IF b > 0 THEN CALL sub
b := b-1;
!b;
END;
PROCEDURE main;
BEGIN
b := a;
CALL sub
END;
CALL main.
~~~~### Logical Expressions
~~~
BEGIN
IF { ODD 1 AND NOT ODD 1} OR NOT ODD 1 THEN
!1
ELSE
!2
END.
~~~### Number guessing game
~~~~
/*
* Number-Guessing Game
*
* 1) Enter random seed (we don't have a random function)
* 2) Happy guessing!
*/
CONST MAXTRIES=5;
VAR in,goal,done,tries;
PROCEDURE calculateGoal;
BEGIN
goal := (in*3)+2;
IF goal < 0 THEN goal := -goal
END;
PROCEDURE main;
BEGIN
done:=0;
tries:=0;
!" GUESS";
!" THE";
!" NUMBER";
!"Enter random number:";
?in;
CALL calculateGoal;
WHILE done = 0 DO
BEGIN
!"Your guess:";
?in;
IF in = goal THEN
BEGIN
!"You won!";
done := 1
END;IF in>goal THEN
BEGIN
!"Smaller!";
tries := tries+1
END;IF in ::= '.'.
::= [ ]
[ ]
{ } .
::= 'CONST' {',' } ';'.
::= ident '=' number.
::= 'VAR' {',' } ';'.
::= ident [ '[' number ']' ].
::= 'PROCEDURE' ident ['(' [ ] ')' ] ';' ';'.
::= 'CALL' ident ['(' [ ] ')' ]
::= ident {',' ident }
::= {',' }
::=
|
|
|
|
|
|
|
| 'RETURN'.
::= 'BEGIN' { ';' STATEMENT } 'END'.
::= '?' ident.
::= '!' (string | ).
::= ident ':=' .
::= '[' ']'.
::= 'IF' 'THEN' ['ELSE' ].
::= 'ODD'
| ('=' | '#' | '<' | '<=' | '>' | '>=') .
::= 'WHILE' 'DO' .
::= 'FOR' '(' ';' '; ')' .
::= ['+' | '-'] term { ('+' | '-') }.
::= { ( '*' | '/' ) }.
::= ident [ ]
| number
| '(' ')'.
::= LOGICAL_TERM {'OR' LOGICAL_TERM}.
::= ['NOT'] LOGICAL_FACTOR {'AND' ['NOT'] LOGICAL_FACTOR}.
::= CONDITION
| ( '{' LOGICAL_EXPRESSION '}').
~~~## Architecture
The compiler has four main components:
- Lexer ([pl0lexer.py](pl0lexer.py))
- Parser ([pl0parser.py](pl0parser.py))
- Namelist ([pl0namelist.py](pl0namelist.py))
- Code-Generator ([pl0codegen.py](pl0codegen.py))### Lexer
The lexical analyzer (short: lexer) transforms source code into tokens and provide them to the parser.
It does this transformation on-demand, when the parser asks for the next token.
One token can be a symbol, number, or a whole variable identifier.
Let's take the Hello-World programm as an example:
~~~~
!"Hello World".
~~~~The lexer would identify and transform this program into the following three tokens:
- SYMBOL (!)
- STRING (Hello World)
- END (.)### Parser
The syntactical analyzer (or parser) tries to resolve the incoming tokens using the syntax-rules of PL/0.
It is designed as a graph-controlled top-down parser with edge-functions. This means that the rules itself
are expressed using a graph and each edge of the graph can have a function which gets called on success.Those functions trigger the code generation or prepare it by for example creating a new variable or checking
if the currently read identifier is already defined. In conclusion it is also possible to detect a few semantical
errors.### Namelist
It manages all procedures, variables and constants of a program. This includes adding and looking for them.### Code-Generation
Provides all commands of the target-language CL/0 such as functions to create jump labels or correct addresses (backpatching).## Vision
The following features/additions came up to my mind while developing the compiler.
Due to a lack of time, they couldn't (and maybe will never) be implemented.
EDIT: The crossed out features managed itself to get to the actual feature list.* ~~ Procedures with arguments ~~
* ~~ Add Return keyword to leave procedure earlier ~~
* ~~ Arrays ~~
* ~~ Connect multiple conditions using logical expressions with AND/OR/NOT ~~
* Procedures with return value
* Modulo division
* Multiple conditions in one If-Condition seperated by AND/OR
* Include other PL/0 files
* Types
* Own VM where with more features (for example more I/O Features to read/write from file/network)
* Real executables instead of vm code (implement x86/x64 code generator)
* Switch-Case
* Break for loops and Switch-Case## Bugs
* ~~ Conditional Statement error on wrong condition. The jmpnot jumps probably to the wrong address ~~
* ~~ Call doesn't work properly. Check out BL5/BL6 ~~
* ~~ Procedure can't access variables of the main programm ~~
* ~~ Procedures with parameters won't work with more than one parameter ~~
* ~~ Order of parameters in Procedures with parameters is wrong ~~
* AST will only be written correctly to xml-file if the compiling process succeeded. On Error some
tags are missing and the xml-file is corrupted.
* (The VM has some segmentation faults under MacOS)## License
(C) 2019 [Raphael Pour](https://raphaelpour.de), licensed under [GPL v3](http://www.gnu.de/documents/gpl-3.0.de.html)