{"id":23280572,"url":"https://github.com/patsaoglou/ooscompiler","last_synced_at":"2025-09-03T23:41:12.909Z","repository":{"id":268312817,"uuid":"878329288","full_name":"patsaoglou/oosCompiler","owner":"patsaoglou","description":"An Object Oriented programming language made using the ANTLR Framework to produce a final C source file that gets compiled into binary using GCC","archived":false,"fork":false,"pushed_at":"2025-01-16T01:44:02.000Z","size":2034,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-22T14:08:04.497Z","etag":null,"topics":["antlr4","c","class-inheritance","compiler","gcc-complier","object-oriented-programming","oop","python-compiler"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/patsaoglou.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-25T07:32:19.000Z","updated_at":"2025-02-26T19:19:11.000Z","dependencies_parsed_at":"2025-04-06T13:35:55.788Z","dependency_job_id":"539d8d64-1380-4e5b-9280-a165cebfe6a0","html_url":"https://github.com/patsaoglou/oosCompiler","commit_stats":null,"previous_names":["patsaoglou/ooscompiler"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/patsaoglou/oosCompiler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patsaoglou%2FoosCompiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patsaoglou%2FoosCompiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patsaoglou%2FoosCompiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patsaoglou%2FoosCompiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patsaoglou","download_url":"https://codeload.github.com/patsaoglou/oosCompiler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patsaoglou%2FoosCompiler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273529144,"owners_count":25121823,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["antlr4","c","class-inheritance","compiler","gcc-complier","object-oriented-programming","oop","python-compiler"],"created_at":"2024-12-19T23:37:20.798Z","updated_at":"2025-09-03T23:41:12.899Z","avatar_url":"https://github.com/patsaoglou.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OOS Compiler Project\nIn this repository, I share a compiler project I've made under the Compilers 2 course (Prof. George Manis). This repository demonstrates the workflow \nof using ANTLR (Another Tool for Language Recognition) to define, parse, and process custom languages. The goal is to illustrate the end-to-end process \nof working with ANTLR, from grammar creation to generating outputs based on parsed input. \n\nA initial grammar file what given to us and we had to implement the listeners \nthat are called once a known grammar structure was recognised by the ANTLR generated lexer and parser. The structure was then used by using the recognised tokens to save the necessary \ninformation into a symbol table structure and generate the final C code once information was enough. \n\n## How ANTLR works\n1. **Defining the Grammar:** begin by writing a grammar file (*.g4) to define the structure and rules of your language. This includes both lexical rules (tokens) and parser rules.\n2. **Generating Lexer and Parser:** Use ANTLR to generate the source code for the lexer, parser, and optional tree traversal classes (listeners or visitors) in the programming language of your choice.\n3. **Parsing Input:** provide the input to the generated parser. The lexer tokenizes the input, and the parser organizes the tokens into a parse tree according to the grammar rules.\n4. **Tree Traversal:** implement custom logic using the generated listener or visitor classes to traverse the parse tree. This step allows you to process the input meaningfully, such as evaluating expressions or transforming code.\n5. **Producing the Output:** based on the traversal, generate the final output, which can be a computed result, transformed data, or any custom representation.\n\n## High-Level OOS code logic\nOOS folows Python's Object Oriented approach where classes can be defined. Classes can encapsulate field of type 'int' or class objects. At least one constructor must also\nbe implemented and called at the final code so the object is initialized by reserving the necessary heap space. \n\nMethod can also be implemented within a class where the given class object 'self' must be passed to link the relation between the class and the method but also in order to be able to perform object manipulation. \n\nMethod within a class can also be overloaded if parameter number is different. OOS supports inheritage where a class can inherit fields and methods from the parent class like they are defined within the class.\n\n## OOS Grammar Structure - ANTLR\nANTLR uses context-free grammar to define the structure of the language. A grammar in ANTLR is defined in the .g4 file, which consists of:\n1. **Lexer Rules:** defines how to tokenize the input string into meaningful pieces (tokens).\n\n```g4\n    WS: [ \\t\\r\\n]+ -\u003e skip;\n    COMMENTS: '#' ~[#]* '#' -\u003e skip;\n    ID: ID_START (ID_CONTINUE)*;\n    INTEGER: NON_ZERO_DIGIT (DIGIT)* | '0'+;\n```\n2. **Parser Rules:** defines how tokens are grouped into higher-level constructs (syntax trees).\n\n```g4\n    statement\n        :   assignment_stat\n        |   direct_call_stat\n        |   if_stat\n        |   while_stat\n        |   return_stat\n        |   input_stat\n        |   print_stat\n        ;\n\n    direct_call_stat\n        :   ('self.')? ID '.' func_call\n        |   ('self.')? func_call\n        ;\n```\n\n## OOS Symbol Table Structure - ANTLR\nA symbol table structure had to be implemented to do the necessary checks if the code recognised by the parser was valid. The stucture had to save \ninformation about the class field definitions, the classes of which it inherites from, the defined constructors and methods. \n\nThe symbol table had to also keep track of the versions of the methods implemented so method overloading was possible. Lastly the symbol table was important for searching if a method or class \nfield seen by the parser was defined in a given class or by inherited classes the programmer specified in the declaration. \n\nThe **def search_method_in_inherited_classes(self, method_name, param_num)** defined in the **symbolTable.py** for example was responsible to search for method not found in the class specified in the oos source code (self parameter) to be searched the inherited class structures saved in the **self.inherits_from = []** in the **class_info** class of the symbol table.\n\nThe information structure saved by the symbol table can be summarized here:\n\n```sym\n    Class name: Shape\n    Fields: [x: int, y: int, color: int]\n    Inherits from: []\n    Methods:\n        Method name: Shape\n        Fields: [self: Shape, x: int, y: int]\n        Parameter num: 3\n        Version: 1\n        Returns: Shape\n        Constructor: True\n    \n        Method name: Shape\n        Fields: [self: Shape, x: int, y: int, color: int]\n        Parameter num: 4\n        Version: 2\n        Returns: Shape\n        Constructor: True\n\n    Class name: Square\n    Fields: [side: int]\n    Inherits from: [Shape]\n    Methods:\n        Method name: Square\n        Fields: [self: Square, side: int]\n        Parameter num: 2\n        Version: 1\n        Returns: Square\n        Constructor: True\n    \n        Method name: get_side\n        Fields: [self: Square]\n        Parameter num: 1\n        Version: 1\n        Returns: int\n        Constructor: False\n```\n\n## From OOS to C source\nThe final conversion of a given OOS source file to the final C source follows the procedure bellow:\n- **Class fields** specified on the OOS source are saved in **typedef struct** of the class name.\n```C\ntypedef struct Shape \n{\n\tint x, y;\n\tint color;\n} Shape;\n```\n- **Class Inheritage** was implemented by saving the class struct of the parent class as a field to the child's struct\nso field space can be reserved during initialization of the object and the object field can be passed when a parent method is called.\n```C\ntypedef struct Square \n{\n\tShape Shape$self;\n\tint side;\n} Square;\n```\n- **Class Objects** on OOS are **struct pointers** in C and not the actual structs so object references are possible and object assignment can happen. If the \nactual struct was used in the field declaration when a object assignment is happening, then the values of the struct would copy to the other struct and we would not have\nthe actual reference of the object in C and any changes happening during a method call would not change the initial object.\n\n```OOS\n    Circle c;\n    Square s;\n```\n\n```C\n\tstruct Circle *c = NULL;\n\tstruct Square *s = NULL;\n```\n\n- **Class Constructor** uses the **malloc** function call to reserve heap space equal to the size of the struct object and return the virtual address memory space to the object's pointer.\n\n```C\nSquare* Square$1$init(Square *self$, int side)\n{\n\tif(self$ == NULL)\n\t{\n\t\tself$ = (Square *)malloc(sizeof(Square));\n\t}\n\n\tself$ -\u003e side = side;\n\n\treturn self$;\n}\n```\n\n- **Method calls** inherited by parent classes are happening by passing the address of the object declared within the child's struct. In the example below we can see how the **SquareWithCirclesOnCorners**\nuses methods declared in the classes that it inherits from:\n\n```C\ntypedef struct SquareWithCirclesOnCorners \n{\n\tSquare Square$self;\n\tCircle Circle$self;\n} SquareWithCirclesOnCorners;\n\nint area$3(SquareWithCirclesOnCorners *self$)\n{\n\tint int_pi;\n\tint_pi = 3;\n\treturn get_side$1(\u0026self$ -\u003e Square$self) * get_side$1(\u0026self$ -\u003e Square$self) + \n        3 * int_pi * get_radius$1(\u0026self$ -\u003e Circle$self) * get_radius$1(\u0026self$ -\u003e Circle$self);\n\n}\n```\n\n## Improvements and additions\n1. The code i've posted cannot support more depth = 1 inheritage since the grammar does not support it and also the search functions\nmight not return the correct value at the end (compiler it might crash too :-).\n2. Since dynamic allocation is used, it is possible to implement automatic deallocation by implenting destructors under the hood that call \nfree() with the actual object's pointer. This can happen by the symbol table keeping track of the references in OOS/pointers in C pointing into a given \nstructure and invoking the destructor method once no more references/pointers hold the object.\n\n# Disclaimers\nThis compiler has no point to be used and is nowhere near of correctly compiling code in general. It was made for educational and experimentation purposes to learn\nabout the ANTLR framework and under semester workload trying to finish within the deadline and delivering optimal result. :-)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatsaoglou%2Fooscompiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatsaoglou%2Fooscompiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatsaoglou%2Fooscompiler/lists"}