Dharm Final Year PDF

Download as pdf or txt
Download as pdf or txt
You are on page 1of 86

Aligarh College of Engineering & Technology, Mathura

Road, Aligarh, 202001

“Online Code Compiler”


A PROJECT REPORT SUBMITTED IN PARTIAL FULFILMENT OF THE
REQUIREMENTS FOR THE AWARD OF THE DEGREE OF

Bachelor of Technology
In
Computer Science and Engineering
Submitted By:
Dharm Solanki (2001090100013)
Under the Guidance of:
Mr. Devendra Sharma

Head of Department: Project In charge:


Dr. Anand Sharma Mr. Rohit Yadav

Dr. A. P. J. Abdul Kalam Technical University, Lucknow


2020-2024
1
DECLARTAION

I hereby declare that the work which is being presented in the B.TECH
Project “Online Code Compiler”, in partial fulfillment of the
requirements for the award of the Bachelor of Technology in
Computer Science and Engineering and submitted to the Department of
Computer Science & Engineering Aligarh College of Engineering and
Technology , is an authentic record of my own work carried under the
supervision of Mr. Devendra Sharma, Professor, Department of
Computer Science and Engineering of Aligarh college of
Engineering and technology .

The contents of this project report, in full or in parts, have not been
submitted to any other institute or university for the award of any
degree.

Sign:
Candidate Name: Dharm Solanki
Roll no: 2001090100013

2
CERTIFICATE
This is to certify that the project entitled “Online Code Compiler”, carried
out Major Project , is a bonafide work by Dharm Solanki (Roll No
2001090100013) have successfully completed in partial fulfillment of the
requirements for the award of the degree Bachelor of Technology
(Computer Science & Engineering) .

Project In charge: Head of Department:


Mr. Rohit Yadav Dr. Anand Sharma
Professor (Computer Science & Eng.) (Computer Science & Eng.)

3
ACKNOWLEDGEMENT
The satisfaction which accompanies the successful completion of the
project is incomplete without the mention of a few names. I take this
opportunity to acknowledge the efforts of the many individuals who helped
me to make this project possible.
Firstly, I would like to express our heartfelt appreciation and gratitude to my
project guide Mr. Devendra Sharma, Professor, Department of
Computer Science and Engineering of Aligarh college of Engineering
and Technology. His vision and execution aimed at creating a structure,
definition and realism around the project and fostered the ideal
environment for me to learn and do. This project is a result of his teaching,
encouragement and inputs in the numerous meetings he had with me,
despite his busy schedule.
The experience was novel one and I would like to thank all the people, who
have let their valuable time for the completion of the report. Without their
consideration it would have been difficult to complete the report.

4
Abstract
Compilers are used to run programs and convert them from a text format to
executable format. A compiler that is to be installed manually on every
system physically requires a lot of space and also configuring of it if not
installed using default parameters. Also once a program is compiled it
becomes platform dependent. It is also not easy to carry the same program
code to multiple systems if situation doesn’t permit the usage of a single
system. Another drawback is that we would need to install a different
complier on each language on which we wish to work. We propose a
solution to this in the form of a cloud- based compiler. Cloud computing is a
model for enabling convenient, on demand network access to a shared
pool of configurable computing resources that can be rapidly provisioned
and released with minimal management effort. Our project aims to create
an online compiler which helps to reduce the problems of portability of
storage and space by making use of the concept of cloud computing. The
ability to use different compilers allows the programmer to pick up the
fastest or the most convenient tool to compile the code and remove the
errors.

Moreover, a web based application can be used remotely through any


network connection which is platform independent. The errors/Output of the
compiled program can be stored in a more convenient way. Also the
trouble of installing a compiler on each computer is avoided. Thus these
advantages make this application ideal for conducting online examinations.
We would be implementing a private cloud on which the software would be
hosted. The software would be provided to the end user using a SAAS
cloud. The software would contain a system that has a text editor and a
terminal. The user would be given an option to select the language in which
he wants to compile the program. The software will compile the program
and return the output to the user. Additional functionalities such as
monitoring of the system, user usage, user forums, and collaborative
development can be added as needed.

5
CONTENTS

Declaration i

Certificate ii

Acknowledgement iii

Abstract iv

List of Figures v

CHAPTER 1 Introduction 8
1.1 About the Project 8
CHAPTER 2 Project Analysis 9
2.1 Purpose of the project 9
2.2 Existing System 18
CHAPTER 3 Requirement Analysis 19
3.1 Purpose and Scope 19
3.2 Users of the System 20
CHAPTER-4 Specific Requirements 21
4.1 Functional and Non Functional requirements 21
4.2 User Interface Requirement 21
4.3 Proposed System Architecture 22

CHAPTER-5 System Requirements 23


5.1 Technologies Used 23
5.2 Tools Used 23
5.3 Software Overview 23

6
5.3.1 NetBeans 24
5.3.2 FireStore DataBase 27
CHAPTER-6 System Design 31
6.1 Behavioral Diagrams 31
6.1.1 Use Case Diagrams 31
6.1.2 Class Diagrams 33
6.1.3 Sequence Diagrams 34
6.1.4 Collaborative Diagrams 39
6.1.5 State Chart Diagrams 43
Chapter-7 System Specific Modules 44
7.1 System Evolution 45
Chapter-8 Testing 46
8.1 Functional Test Cases 46
8.2 Integration Test cases 46
8.3 Database Tables 48
Chapter-9 Output Screens 50
Chapter 10 Code 61
Chapter-11 Conclusion And Features 85
Bibilography 86

7
1. Introduction
1.1 About Project
The main aim of this project is we can easily write a java, C, C++, python program and compile
it and debug in on-line. The client machine doesn’t have java development kit .The client
machine is only connected to the server having java compiler ,so server executes the java code
produces the error message to the appropriate client machine.

In this project is also creates a security editor. This editor performs Encryption and decryption of
the file. These processes are performed using RSA Algorithms. There is lot of security
algorithms, but RSA algorithm is most efficient to encrypt and decrypt the file.

In this project it is used to view all type of java API .It is very useful for writing the java program
easily, for example if any error in the format of API there is a possibility to view API thr The
main objective of the project is to visualize the things that goes under each and every phase of a
compiler. With the help of this product the users can easily understand the compiler. In this
project it visualizes the java programs.

In the first phase, it visualizes the tokens that are identified from the uploaded java
program done by the user. In the second phase, it generates the parse trees both in top-down and
bottom-up view based on the tokens. In the third phase, it shows the semantic view that
concentrates on syntax checking and type-casting operation.
In the fourth phase, it generates the intermediate code based on the syntax trees. In the
fifth phase, it removes the unnecessary temporary variables from the intermediate code. Finally,
the output will be displayed for the given program.
own through this module.

8
2. Project Analysis
2.1 Purpose of the Project:
The main purpose of this project is to help the users to know the things that goes under each and
every phase of a compiler. To make them understand about complete process of compilation, to
provide them about knowledge of programming languages implementation and their
dependencies with system architecture.
The phases of a compiler are described as follows:

1.Lexical Analysis

This is alternatively known as scanning or tokenization. Lexical Analysis is roughly the


equivalent of splitting ordinary text written in a natural language (e.g. English) into a sequence
of words and punctuation symbols.

The purpose of lexical analysis is to convert a source program expressed as characters (arranged
on lines) into a sequence of valid tokens. Note that this is not the same as a valid sequence of
tokens.

Token:

1. In computing, a token is a categorized block of text, usually consisting of indivisible


characters known as lexemes.

2. A lexical analyzer initially reads in lexemes and categorizes them according to function,
giving the3. A token can look like anything: English, gibberish symbols, anything; it just needs
to be a useful part of the structured text.

4. Tokens are frequently defined by regular expressions, which are understood by a lexical
analyser such as lex.

5. The lexical analyser reads in a stream of lexemes and categorises them into tokens. This is
called "tokenizing." If the lexer finds an invalid token, it will report an error.

9
6. Following tokenizing is parsing. From there, the interpreted data may be loaded into data
structures, for general use, interpretation, or compiling.

Consider the following table:

Lexeme Token

Sum IDENT

= ASSIGN_OP

3 NUMBER

+ ADD_OP

2 NUMBER

; SEMICOLON

Consider a text describing a calculation:

"46 - Number of (cows);”

The lexemes here might be: "46", "-", "number of", "(", "cows", ")", and ";".

The lexical analyser will denote lexemes 4 and 6 as 'number'

and - as character, and 'number of ' as a separate token. Even the lexeme ';' in some languages
(such as C) has some special meaning.

7. The whitespace lexemes are sometimes ignored later by the syntax analyser. A token doesn't
need to be valid, in order to be recognized as a token. "Cows" may be nonsense to the language,
"number of" may be nonsense. But they are tokens none the less, in this example.

10
2.Syntax Analysis:

This is alternatively known as parsing. It is roughly the equivalent of checking that some
ordinary text written in a natural language (e.g. English) is grammatically correct (without
worrying about meaning).

The purpose of syntax analysis or parsing is to check that we have a valid sequence of tokens.
Note that this sequence need not be meaningful; as far as syntax goes, a phrase such as "true + 3"
is valid but it doesn't make any sense in most programing languages.

Recursive Descent Parsing

A recursive descent parser is a top-down parser built from a set of mutually-recursive


procedures (or a non-recursive equivalent) where each such procedure usually implements one of
the production rules of the grammar. Thus the structure of the resulting program closely mirrors
that of the grammar it recognizes.

A predictive parser is a recursive descent parser with no backup. Predictive parsing is


possible only for the class of LL(k) grammars, which are the context-free grammars for which
there exists some positive integer k that allows a recursive descent parser to decide which
production to use by examining only the next k tokens of input. (The LL(k) grammars therefore
exclude all ambiguous grammars, as well as all grammars that contain left recursion. Any
context-free grammar can be transformed into an equivalent grammar that has no left recursion,
but removal of left recursion does not always yield an LL(k) grammar.) A predictive parser runs
in linear time.

Recursive descent with backup is a technique that determines which production to use by
trying each production in turn. Recursive descent with backup is not limited to LL(k) grammars,
but is not guaranteed to terminate unless the grammar is LL(k). Even when they terminate,
parsers that use recursive descent with backup may require exponential time.

Although predictive parsers are widely used, programmers often prefer to create LR or
LALR parsers via parser generators without transforming the grammar into LL(k) form.

11
Some authors define the recursive descent parsers as the predictive parsers. Other authors use the
term more broadly, to include backed-up recursive descent.[citation needed]

Operator Precedence Parsing

Operator precedence parsing is used in shift-reduce parsing. operator grammar No


production has two nonterminal symbols in sequence on the right hand side. An operator
grammar can be parsed using shift-reduce parsing and precedence relations between terminal
symbols to find handles. This strategy is known as operator precedence.

Using the generated Token manager

In order to use the generated token manager, an instance of it has to be created. When
doing so, the constructor expects a Reader as the source of the input data Once created, the token
manager object can be used to get tokens via the

Token ParserNameTokenManager.getNextToken() throws ParseError;

Each Token object as returned by the getNextToken() method. Such a Token object provides a
field kind which identifies the token (ParserNameConstants.java defines the corresponding
constants). It also contains the field image, which just holds the matched input data as a String.

3.Semantic Analysis:

This is roughly the equivalent of checking that some ordinary text written in a natural language
(e.g. English) actually means something (whether or not that is what it was intended to mean).

The purpose of semantic analysis is to check that we have a meaningful sequence of tokens. Note
that a sequence can be meaningful without being correct; in most programming languages, the
phrase "x + 1" would be considered to be a meaningful arithmetic expression. However, if the
programmer really meant to write "x - 1", then it is not correct.

12
4.Code Optimization:

Intermediate Representation

The form of the internal representation among different compilers varies widely. If the back end
is called as a subroutine by the front end then the intermediate representation is likely to be some
form of annotated parse tree, possibly with supplementary tables. If the back end operates as a
separate program then the intermediate representation is likely to be some low-level pseudo
assembly language or some register transfer language (it could be just numbers, but debugging is
easier if it is human-readable).

Optimization

Optimization within a compiler is concerned with improving in some way the generated object
code while ensuring the result is identical. Technically, a better name for this chapter might be
"Improvement", since compilers only attempt to improve the operations the programmer has
requested.

Optimizations fall into three categories:

 Speed; improving the runtime performance of the generated object code. This is the most
common optimization
 Space; reducing the size of the generated object code
 Safety; reducing the possibility of data structures becoming corrupted (for example,
ensuring that an illegal array element is not written to)

Unfortunately, many "speed" optimizations make the code larger, and many "space"
optimizations make the code slower -- this is known as the space-time tradeoff.

Common Optimization Algorithms

Common optimization algorithms deal with specific cases:

1. Dead Code Elimination

13
2. Common Sub-expression Elimination
3. Copy Propagation
4. Code Motion
5. Induction Variable Elimination
6. Reduction In Strength
7. Function Chunking

Dead Code Elimination

Dead code elimination is a size optimization (although it also produces some speed
improvement) that aims to remove logically impossible statements from the generated object
code. Dead code is code which will never execute, regardless of input

Consider the following program:

a=5
if (a != 5) {
// Some complicated calculation } …

It is obvious that the complicated calculation will never be performed; since the last value
assigned to a before the if statement is a constant, we can calculate the result at compile-time.
simple substitution of arguments produces if (5 != 5), which is false. Since the body of an
if(false) statement will never execute - it is dead code we can rewrite the code:

a=5
// Some statements

The algorithm was used to identify and remove sections of dead code

Common Sub-expression Elimination

Common sub-expression elimination is a speed optimization that aims to reduce unnecessary


recalculation by identifying, through code-flow, expressions (or parts of expressions) which will
evaluate to the same value: the recomputation of an expression can be avoided if the expression

14
has previously been computed and the values of the operands have not changed since the
previous computation.

Consider the following program:

a=b+c
d=e+f
g=b+c

In the above example, the first and last statement's right hand side are identical and the value of
the operands do not change between the two statements; thus this expression can be considered
as having a common sub-expression.

The common sub-expression can be avoided by storing its value in a temporary variable which
can cache its result.

After applying this Common Sub-expression Elimination technique the program becomes:

t0 = b + c
a = t0
d=e+f
g = t0

Thus in the last statement the re-computation of the expression b + c is avoided.

Code Motion

This optimization technique mainly deals to reduce] the number of source code lines in the
program. For example, consider the code below:

for (i = 0; i < n; ++i) {


x = y + z;
a[i] = 6 * i + x * x;
}

15
The calculations x = y + z and x * x can be moved outside the loop since within they are loop
invariant - they do not change over the iterations of the loop - so our optimized code will be
something like this:

x = y + z;
t1 = x * x;
for (i = 0; i < n; ++i) {
a[i] = 6 * i + t1;
}

This code can be optimized further. For example, strength reduction could remove the two
multiplications inside the loop (6*i and a[i]).

Induction Variable Elimination

Function Chunking

Function chunking is a compiler optimization for improving code locality. Profiling information
is used to move rarely executed code outside of the main function body. This allows for memory
pages with rarely executed code to be swapped out.

5.Code Generation

1. Actually, A compiler usually is designed to output an executable program that will allow the
user to run your program, and to be directly run by the processor, without having an intermediary
interpreter such as in the interpretation process. For your program to be run by the processor
however, you will need to transform the instructions in your specific programming language into
assembler code, which is then sent to an assembler tool to create object code, which is then
linked together with specific libraries to create your executable code.

2. For now, we only really need to worry about transforming the instructions into assembler
code. If you intend your programs to run on the x86 architecture, you need to be familiar with
x86 assembler code, and so on.

16
3. Code generation occurs after semantic analysis is done, which gives us enough information to
generate more primitive concrete code. The general idea behind code generation is decompose
the tree structure of the syntax tree into a sequence of instructions, whatever an instruction set is.

4. In this stage, since we are done with the semantic program, we are not interested in the
syntactic and semantic structure of programs but in the order of executions of instructions.

5. Sometimes it may be beneficial to output some sort of intermediate code is often produced
before generating actual machine code.

The benefits of this are:-

1. It is easier to generate more abstract code, not bothering too much about things like register
allocations,
2. Optimization independent to machine architecture can be done and
3. Compiler bugs can be spotted more easily.

However, it may be simpler for the program to output assembler code directly, but lose the
above advantages.

The three address format is used to represent the intermediate code. The format is useful because
it is analogous to actual machine instructions in some architectures and, more importantly,
allows us to easily change the execution order of instructions, which is an huge advantage over
stack-based intermediate code like the byte code of Java.

Although is not a complex problem to reuse names after they have already been used, it is
actually beneficial to allocate a new name every time one is needed because it allows us to form
a call graph and optimize easily .

The three address code, as the name suggests, consist of three address and opcode, which tells
what kind of operation is meant to be done.

For example, an expression (a + b) * 3 can be transformed into:

17
temp1 := a + b; temp2 := temp1 * 3

In the first line, temp1, a and b are addresses and + is an opcode, and the second line is similar to
the first one. Unlike load-store machines, it is unnecessary to load variables to registers and store
them back. You see why the three address code is easy to handle.

Choosing portable, flexible and expressive instructions is critical; Not having enough
instructions can complicate generated code with the combination of several instructions to
achieve one operation and having too much may obviously make maintenance more daunting
task. Probably the best way to do this is to examine existing machine code. It is more
straightforward to transform code close to underlying machine code than abstract one.

Expression

Algebraic expressions can be translated into the three address code in a very straightforward
manner. This can be done rather recursively as follows: Assume two expressions left and right
with an operation op-code, then the results should be:

code for left


code for right
temp = place for left + place for right

2.2 Existing System:


At present , Students prefer text books to gain knowledge about the Compiler but they don’t
extract the exact things from the text book as the human nature is that if we see the actual
process with our eyes we will not forget it in our life time.
2.2.1 Problems in Existing System:
i. Takes time to understand the compiler process.
ii. User cannot understand completely about the compiler process.
2.2.2Proposed system:
By using this system there are following advantages:
1. By using this system user can easily understand the compiler.
2. User can save his/her time by using this system.

18
3. Requirement Analysis
3.1 Purpose and Scope:
The main purpose of this project is to help the users to know the things that goes under
each and every phase of a compiler. To make them understand about complete process of
compilation, to provide them about knowledge of programming languages implementation and
their dependencies with system architecture.
1. Any compiler has some essential requirements, which are perhaps more stringent than for
most programs:

a)Any valid program must be translated correctly, i.e. no incorrect translation is allowed.

b)Any invalid program must be rejected and not translated.

2. There will inevitably be some valid programs which can't be translated due to their size or
complexity in relation to the hardware available.

for example, problems due to memory size.

3. The compiler may also have some fixed-size tables which place limits on what can be
compiled (some language definitions place explicit lower bounds on the sizes of certain tables, to
ensure that programs of reasonable size/complexity can be compiled).

4.There are also some desirable requirements, some of which may be mutually exclusive:

a)Errors should be reported in terms of the source language or program.

b)The position at which an error was detected should be indicated; if the actual error
probably occurred somewhat earlier then some indication of possible cause(s) should also be
provided.

c)Compilation should be fast.

d)The translated program should be fas

19
5. If the source language has some national or international standard:

a)Ideally the entire standard should be implemented.

b)Any restrictions or limits should be well and clearly documented.

6.If extensions to the standard have been implemented:

a)These extensions should be documented as such.

b)There should be some way of turning these extensions off.

7. There are also some possibly controversial requirements to consider:

a) Errors detected when the translated program is running should still be reported in relation to
the original source program e.g. line number.

b)Errors detected when the translated program is running should include division by 0, running
out of memory, use of an array subscript/index which is too big or too small, attempted use of an
undefined variable, incorrect use of pointers, etc.

3.2 Users of the System:


a. Student
b.Faculty
c.Programmer
d.Software Engineer

20
4. Specific Requirements
4.1 Functional and Non- Functional Requirements :
Functional Requirements :
1. Accept the source code as an input.
2. Translate the input file into lexemes.
3. Provides Visualization for the translated lexemes.
4. Construct Parse trees for the lexemes.
5. Provide Visualization for the Parse trees.
6. Create a stream of simple instructions from the parse trees.
7. Provides Visualization for the instructions formed.
8. Optimal code generation from the intermediate code generated.
9. Provide Visualization for the optimal code.
10. Object code generation for the Optimized code.
11. Provide Visualization for the object code.
12. Keeps track of names used by the program in symbol table.
13. Error flaw detection is done in the error-handler.
Non- Functional Requirements:
1 .Secure access of confidential data(user’s details).SSL can be used.
2. 24x7 availability.
3. Better component design to get better performance at peak time.
4. Flexible service based architecture will be highly desirable for future for
extension.

4.2 User Interface Requirements:


A. Professional look and feel
B. Use of AJAX atleast with all registration forms
C. Use of Graphical tool to show strategic data to admin
D. Reports exportable in .XLS, .PDF or any other desirable format.

21
4.3 Proposed System Architecture :

Figure1: Architecture Diagram

22
5. System Requirements
5.1 Technologies Used:
1. JavaScript
2. Java Database Connectivity (JDBC)
3. Unified Modeling Language (UML)
4. React Js
5. Tailwind CSS
5.2 Tools Used
1. Firebase
2. Judge0
3. Netbeans
4. FireStore
5. MonacoEditor
5.3 Software Overview

23
5.3.1 Netbeans
NetBeans Platform Features
Why would you use the NetBeans Platform? What does the NetBeans Platform give you? Many
out-of-the-box components and much else besides.

The main reusable features and components comprising the NetBeans Platform are outlined
below.

Module System

The modular nature of a NetBeans Platform application gives you the power to meet complex
requirements by combining several small, simple, and easily tested modules encapsulating
coarsely-grained application features.

Powerful versioning support helps give you confidence that your modules will work together,
while strict control over the public APIs your modules expose will help you create a more
flexible application that's easier to maintain.

Since your application can use either standard NetBeans Platform modules or OSGi bundles,
you'll be able to integrate third-party modules or develop your own.

Lifecycle Management

Just as application servers, such as GlassFish or WebLogic, provide lifecycle services to web
applications, the NetBeans runtime container provide lifecycle services to Java desktop
applications.

Application servers understand how to compose web modules, EJB modules, and related
artifacts, into a single web application. In a comparable manner, the NetBeans runtime
container understands how to compose NetBeans modules into a single Java desktop
application.

24
There is no need to write a main method for your application because the NetBeans Platform
already contains one. Also, support is provided for persisting user settings across restart of the
application, such as, by default, the size and positions of the windows in the application.

Pluggability, Service Infrastructure, and File System

End users of the application benefit from pluggable applications because these enable them to
install modules into their running applications.

NetBeans modules can be installed, uninstalled, activated, and deactivated at runtime, thanks
to the runtime container.

The NetBeans Platform provides an infrastructure for registering and retrieving service
implementations, enabling you to minimize direct dependencies between individual modules
and enabling a loosely coupled architecture (high cohesion and low coupling).

The NetBeans Platform provides a virtual file system, which is a hierarchical registry for storing
user settings, comparable to the Windows Registry on Microsoft Windows systems. It also
includes a unified API providing stream-oriented access to flat and hierarchical structures, such
as disk-based files on local or remote servers, memory-based files, and even XML documents.

Window System, Standardized UI Toolkit, and Advanced Data-Oriented Components

Most serious applications need more than one window. Coding good interaction between
multiple windows is not a trivial task. The NetBeans window system lets you
maximize/minimize, dock/undock, and drag-and-drop windows, without you providing any
code at all.

Swing and JavaFX are the standard UI toolkits on the Java desktop and can be used throughout
the NetBeans Platform. Related benefits include the ability to change the look and feel easily
via "Look and Feel" support in Swing and CSS integration in JavaFX, as well as the portability of
GUI components across all operating systems and the easy incorporation of many free and
commercial third-party Swing and JavaFX components.
25
With the NetBeans Platform you're not constrained by one of the typical pain points in Swing:
the JTree model is completely different to the JList model, even though they present the same
data. Switching between them means rewriting the model. The NetBeans Nodes API provides a
generic model for presenting your data. The NetBeans Explorer & Property Sheet API provides
several advanced Swing components for displaying nodes.

In addition to a window system, the NetBeans Platform provides many other UI-related
components, such as a property sheet, a palette, complex Swing components for presenting
data, a Plugin Manager, and an Output window.

Miscellaneous Features, Documentation, and Tooling Support


The NetBeans IDE, which is the software development kit (SDK) of the NetBeans Platform,
provides many templates and tools, such as the award winning Matisse GUI Builder that
enables you to very easily design your application's layout.

The NetBeans Platform exposes a rich set of APIs, which are tried, tested, and continually being
improved.

The community is helpful and diverse, while a vast library of blogs, books, tutorials, and training
materials are continually being developed and updated in multiple languages by many different
people around the world.

26
5.3.2 FireStore DataBase
We have two options with Firebase, i.e., Firebase Real-time Database, which we
learned in our previous section and Cloud Firestore. Cloud Firestore is newer, but it is
not replacing the Firebase Real-time Database. Cloud Firestore is a flexible as well as
scalable NoSQL cloud database. It is used to store and sync data for client and server-
side development. It is used for mobile, web, and server development from Google
Cloud Platform and Firebase. Like the Firebase Real-time Database, it keeps syncing
our data via real-time listeners to the client app. It provides offline support for mobile
and web so we can create responsive apps that work regardless of network latency or
Internet connectivity.

Cloud Firestore also provides seamless integration with Google Cloud Platform
products and other Firebase, including cloud functions.

Key capabilities

Flexibility

The Firestore data model supports a flexible, hierarchical data structure. It stores our
data in the document, which is organized into a collection. In Firestore, the documents
can contain complex nested objects rather than sub-collections

Expressive querying

In Firestore, we can use queries for retrieving specific, individual documents or for
retrieving all the documents in a collection that match our query parameters. Our
queries combine filtering and sorting and can include multiple, chained filters. The query
performance is proportional to the size of our result set because queries are indexed by
default.

Real-time updates

Firestore is quite similar to Firebase Realtime Database. Firestore also uses data
synchronization for updating data on any connected device. It is designed for making
simple one time fetch queries efficiently.

Offline Supports

Cloud Firestore enables us to make a cache of the app data, which it is actively using.
This makes the app to read, write, query, and listen to the data even when the device is
offline. When the device comes in an online mode, Cloud Firestore synchronizes the
local changes back to it.

27
Designed to scale

Cloud Firestore provides us the best infrastructure of the Google Cloud Platform:
automated multi-region data replication, atomic batch operations, strong consistency
guarantees, and real transaction support. We designed Cloud Firestore for handling the
toughest database workloads from the world's largest apps.

How does it work?

Cloud Firestore, a cloud-hosted, NoSQL database, is accessed directly through the


native SDK by our iOS, Android, and web apps. In addition to REST and RPC APIs,
Cloud Firestore is also available in native Node.js, Java, Python, and Go SDKs.

After Cloud Firestore's NoSQL data model, we can store data in documents that have
field mappings for values. The documents are stored in a container called collections.
These containers are used to organize our data and create queries. There are different
data types, from simple string and numbers to complex nested objects, supported by
documents. We can also create sub-collection within a document and create a
hierarchical data structure that scales to the growth of our database. The Firestore data
model supports whatever data structure works best for our app.

Additionally, the query in Cloud Firestore is expressive, efficient, and flexible. The
shallow queries are created to retrieve data at the document level without the need to
retrieve the entire collection or any nested subdivision. Add sorting, filtering, and limits
for our queries or cursors to index the result. Add a real-time listener to our app for
keeping the data running. Every time it is updated without recovering our entire
database.

Adding real-time listeners to our app informs us with a data snapshot whenever our
customer apps are changing data, only getting new changes.

For protecting our data access in Cloud Firestore, Firebase authentication, and Cloud
Firestore security rules are used for Identity and Access Management (IAM).

Features of Firestore

There are the following features of Firestore:

28
Security

For data, Cloud Firestore has built-in security access controls. It enables simple data
validation via a configuration language.

Datastore mode

Cloud Firestore supports the Datastore API. We don't need to make any changes to our
existing Datastore apps. We can expect similar performance characteristics and pricing
with the added benefit of strong stability.

Automatic upgrade

The Cloud Datastore database will be upgraded shortly and natively after the GA
release of Cloud Firestore. No code changes are required, and there is no downtime for
our app.

ACID transaction

Cloud Firestore has support for transactions, so if any operations in the transaction fail
(and cannot be withdrawn), then the entire transaction will fail.

Multi-region replication

With the help of automatic multi-region replication and strong stability, our data is safe
and available, even when disasters strike.

Powerful query engine

29
Cloud Firestore allows us to run sophisticated queries against our NoSQL data without
any degradation in performance. This gives us more flexibility to structure our data.

Built for cloud-native applications

Mobile and web applications are included by the typical workloads which collaborate
with the multi-user, retail product catalogs, IoT asset tracking, social user-profiles and
activity, communications, and gaming leaderboards.

30
6. System Design
6.1Behavioral Diagrams :
6.1.1 Use Case Diagrams :
Use Case : User actions

Fig 2 : use case of the system

31
Description:
Name of the Use Case: Login
Description: Every user of the product must be login to view the compiler process .
Pre-condition: Each user must have a valid user id and password.
Post condition: Uploading file page will be displayed.
Flow of events:
 Invoke the Welcome page of System.
 Enter the valid User ID and Password.
 Click on Sign In button to access Uploading page.
Alternative Flow of Events:
 If the user is new Click on Registration Link.

Name of The Use Case: Uploading a file


Description: The user can upload a java file
Pre-condition: The User must be logged into the system.
Post condition: views all phases.
Flow of events:
 Login to the Home Page.
 Uploads the file.

32
6.1.2 Class Diagrams:
For User:

Fig:3 :Class Diagram for Visualization of Compiler Phases

33
6.1.3 Sequence Diagrams:
A sequence diagram represents the sequence and the interactions of given case or
scenario. A sequence diagram shows an interaction arranged in a time sequence.

Login and Registration:

c:customer h:homepage d:Database

Register(fname,lname,uid,pswd)
Update the database
verify if uid already exists
Updated successfully

Login(uid.pswd)
compare in db
Verify for validity
Successfully logged in

FIGURE 4: Sequence Diagram for Login and Registration

Description:

1. Customer enters userid and password in the Login screen.


2. login screen get details from database and verifies these details in database.
3: If user is valid then he can view homepage.
4. If he is not valid, then he has to register.
5. Successful registration will be displayed.

34
Sequence diagram for Uploading a file:

c:customer l:login h:home page

login
verifies
valid

Upload a file

FIGURE 5: Sequence Diagram for Updating a file

Sequence diagram for Lexical phase

c:customer l:login h:home page

login
verifies
valid

Upload a file

Uploaded Successfully

View Lexical Phase

FIGURE 6: Sequence Diagram for Lexical phase

35
Sequence diagram for Syntax Phase

c:customer l:login h:home page

login
verifies
valid

Upload a file

Uploaded Successfully

View syntax phase

FIGURE 7:Sequence Diagram for Syntax phase

Sequence diagram for Semantic phase

c:customer l:login h:home page

login
verifies
valid

Upload a file

Uploaded Successfully

View semantic phase

FIGURE8:Sequence diagram for Semantic phase

36
Sequence diagram for Intermediate code Phase

c:customer l:login h:home page

login
verifies
valid

Upload a file

Uploaded Successfully

View Intermediate code phase

FIGURE 9: Sequence Diagram for Intermediate code


Sequence diagram for Code Optimization Phase

c:customer l:login h:home page

login
verifies
valid

Upload a file

Uploaded Successfully

View code optimization phase

FIGURE 10: Sequence Diagram for Code Optimization

37
Sequence diagram for Code Generation Phase

c:customer l:login h:home page

login
verifies
valid

Upload a file

Uploaded Successfully

View code generation phase

FIGURE 11: Sequence Diagram for Login and Registration

38
6.1.4 Collaboration Diagrams :
This diagram is an interaction diagram that stresses or emphasizes the structural
organization of the objects that send and receive messages. It shows a set of objects, links
between objects and messages send and received by those objects. There are used to illustrate the
dynamic
views of a system.
Collaboration Diagram for Login and Registration:

1: Register(fname,lname,uid,pswd)
c:custo 5: Login(uid.pswd)
mer
h:homep
age

4: Updated successfully 3: verify if uid already exists


8: Successfully logged in 7: Verify for validity 2: Update the database
6: compare in db

d:Databa
se

FIGURE 12: Collaboration Diagram for Login and Registration.

39
Collaboration Diagram for Lexical Phase:

2: verifies

1: login
c:custo l:login
mer
3: valid

4: Upload a file
6: View Lexical Phase

5: Uploaded Successfully

h:home
page

FIGURE 13: Collaboration Diagram for Lexical phase.

Collaboration diagram for Syntax Phase

2: verifies

1: login
c:custo l:login
mer
3: valid

4: Upload a file
6: View syntax phase

5: Uploaded Successfully

h:home
page

FIGURE 14: Collaboration Diagram for Syntax phase.

40
Collaboration diagram for Semantic Phase

2: verifies

1: login
c:custo l:login
mer
3: valid

4: Upload a file
6: View semantic phase

5: Uploaded Successfully

h:home
page

FIGURE 15: Collaboration Diagram for Semantic phase

2: verifies

1: login
c:custo l:login
mer
3: valid

4: Upload a file
6: View Intermediate code phase

5: Uploaded Successfully

h:home
page

41
Collaboration diagram for Code Optimization phase

2: verifies

1: login
c:custo l:login
mer
3: valid

4: Upload a file
6: View code optimization phase

5: Uploaded Successfully

h:home
page

FIGURE 17: Collaboration Diagram for Code optimization


Collaboration diagram for Code Generation Phase

2: verifies

1: login
c:custo l:login
mer
3: valid

4: Upload a file
6: View code generation phase

5: Uploaded Successfully

h:home
page

42
6.1.5 State Chart Diagrams :
State chart diagram shows a state machine consisting of states, transitions and activities these
illustrates the dynamic view of a system. They focus on the event ordered.

Login :

FIGURE 19: State Chart Diagram for Login.

43
7. System Specific Modules

1. Login and Registration:


In this module a customer first login in to the system if he is already registered then he is
authenticated user. Suppose a customer is not authenticated then he is first registered into system.

2. Uploading file:
In this module a customer can upload the file so that he/she can view all the phases of a java
compiler.

3. Lexical Phase:
In this module the tokens will be identified from the uploaded java file and are displayed to
the user.

4. Syntax Phase:
In this module parse trees were constructed from the identified tokens and are displayed to user in
both top-down and bottom-up order.

5. Semantic Phase:
In this module it verifies whether the syntax is right or not and performs type-casting
operation..

6. Intermediate Code Generation:


In this module it displays the intermediate code for the uploaded java file.

7. Code Optimization:

44
In this module it removes the unnecessary temporary variables from the intermediate code and
displays it to the user.
8. Code generation:
In this module it displays the actual output of the program.

7.1 System Evolution


System to be changed:
Generally, Students prefer text books to gain knowledge about the Compiler but they don’t
extract the exact things from the text book as the human nature is that if we see the actual
process with our eyes we will not forget it in our life time.
Change Proposals:
The change proposal to the existing system is that exists today, where user can save time and
easily understand what the compiler process is by using this system.
Change Analysis:
Here student can upload any java program and view the outputs of each and every phase of a
compiler.
System understanding:
Complete understanding of the system that is to be generated i.e. a brief study of the
requirements and Designing the system that is to be developed
System Validation:
Validation can be fined in many ways, but a simple definition is that validation succeeds when
software functions in a manner that can be reasonably expected by the customer, i.e. the
customer expected output i.e. fulfilling all the customer specified requirements.
Modified System:
The modified system from the existing system is the Visualization of compiler phases.This is
very
effective to students .

45
8.Testing
8.1 Functional Test cases:

Table 1. Functional Test cases for Visualization of compiler phases.

8.2Integration Test cases :

TEST CASE DESCRIPTIO TEST EXPECTED ACTU REMARKS DE


ID N STEPS RESULT AL FE
RESU CT
LT ID
Upload_2 Verify the Run reg.java Upload page of
outputs of and verify user should be
every phase. userid and displayed.
password
Click on Verify whether
upload the file is
button. uploaded
successfully.
Phases_7

Click on Verify whether


submit Lexical phase
button. output is
obtained for
the given
program or not.
click on next Verify whether
button. Syntax phase

46
output is
obtained or
not.

Verify reports Click on Verify


and graphs the next whether
based on items button semantic
sold. phase output
is obtained
or not.

Click on Verify
next whether
button. Intermediate
code is
obtained or
not.
Click on Verify
next whether
button. Code
Optimizatio
n phase is
obtained or
not.
Click on Verify
the next whether
button Final output
is obtained
or not.

47
Table .2. Integration Test cases for Visualization of Compiler Phases.
8.3 Database Tables

48
49
9 Output Screens

LOGIN SCREEN:

50
AFTER SUCCESSFULLY LOGIN:

51
USER DETAILS:

52
COMPILER TO CODE:

53
CODE INPUT/OUTPUT AND STATUS:

54
ERROR STATUS :

55
SIGN UP PAGE:

56
IF USER EXIST:

57
AFTER SUCCESSFUL REGISTRATION:

58
PROTECTED ROUTES WITHOUT LOGIN:

59
60
Code:

Folder Structure & Components:

61
Landing.js:

import React, { useEffect, useState } from "react";


import CodeEditorWindow from "./CodeEditorWindow";
import axios from "axios";
import { classnames } from "../utils/general";
import { languageOptions } from "../constants/languageOptions";

import { ToastContainer, toast } from "react-toastify";


import "react-toastify/dist/ReactToastify.css";

import { defineTheme } from "../lib/defineTheme";

62
import useKeyPress from "../hooks/useKeyPress";
import Footer from "./Footer";
import OutputWindow from "./OutputWindow";
import CustomInput from "./CustomInput";
import OutputDetails from "./OutputDetails";
import ThemeDropdown from "./ThemeDropdown";
import LanguagesDropdown from "./LanguagesDropdown";
import { auth, db } from "./Firebase";
import { doc, getDoc } from "https://www.gstatic.com/firebasejs/10.11.0/firebase-
firestore.js";

const javascriptDefault = `/**


* Problem: Binary Search: Search a sorted array for a target value.
*/

// Time: O(log n)
const binarySearch = (arr, target) => {
return binarySearchHelper(arr, target, 0, arr.length - 1);
};

const binarySearchHelper = (arr, target, start, end) => {


if (start > end) {
return false;
}
let mid = Math.floor((start + end) / 2);
if (arr[mid] === target) {
return mid;
}
if (arr[mid] < target) {
return binarySearchHelper(arr, target, mid + 1, end);
}
if (arr[mid] > target) {
return binarySearchHelper(arr, target, start, mid - 1);
}
};

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];


const target = 5;
console.log(binarySearch(arr, target));
`;

const Landing = () => {


const [code, setCode] = useState(javascriptDefault);
const [customInput, setCustomInput] = useState("");
const [outputDetails, setOutputDetails] = useState(null);

63
const [processing, setProcessing] = useState(null);
const [theme, setTheme] = useState("cobalt");
const [language, setLanguage] = useState(languageOptions[0]);

const enterPress = useKeyPress("Enter");


const ctrlPress = useKeyPress("Control");

const onSelectChange = (sl) => {


console.log("selected Option...", sl);
setLanguage(sl);
};

useEffect(() => {
if (enterPress && ctrlPress) {
console.log("enterPress", enterPress);
console.log("ctrlPress", ctrlPress);
handleCompile();
}
}, [ctrlPress, enterPress]);
const onChange = (action, data) => {
switch (action) {
case "code": {
setCode(data);
break;
}
default: {
console.warn("case not handled!", action, data);
}
}
};
const handleCompile = () => {
setProcessing(true);
const formData = {
language_id: language.id,
// encode source code in base64
source_code: btoa(code),
stdin: btoa(customInput),
};
const options = {
method: "POST",
url: process.env.REACT_APP_RAPID_API_URL,
params: { base64_encoded: "true", fields: "*" },
headers: {
"content-type": "application/json",
"Content-Type": "application/json",

64
"X-RapidAPI-Host": process.env.REACT_APP_RAPID_API_HOST,
"X-RapidAPI-Key": process.env.REACT_APP_RAPID_API_KEY,
},
data: formData,
};

axios
.request(options)
.then(function (response) {
console.log("res.data", response.data);
const token = response.data.token;
checkStatus(token);
})
.catch((err) => {
let error = err.response ? err.response.data : err;
// get error status
let status = err.response.status;
console.log("status", status);
if (status === 429) {
console.log("too many requests", status);

showErrorToast(
`Quota of 100 requests exceeded for the Day! Please read the blog on
freeCodeCamp to learn how to setup your own RAPID API Judge0!`,
10000
);
}
setProcessing(false);
console.log("catch block...", error);
});
};

const checkStatus = async (token) => {


const options = {
method: "GET",
url: process.env.REACT_APP_RAPID_API_URL + "/" + token,
params: { base64_encoded: "true", fields: "*" },
headers: {
"X-RapidAPI-Host": process.env.REACT_APP_RAPID_API_HOST,
"X-RapidAPI-Key": process.env.REACT_APP_RAPID_API_KEY,
},
};
try {
let response = await axios.request(options);
let statusId = response.data.status?.id;

65
// Processed - we have a result
if (statusId === 1 || statusId === 2) {
// still processing
setTimeout(() => {
checkStatus(token);
}, 2000);
return;
} else {
setProcessing(false);
setOutputDetails(response.data);
showSuccessToast(`Compiled Successfully!`);
console.log("response.data", response.data);
return;
}
} catch (err) {
console.log("err", err);
setProcessing(false);
showErrorToast();
}
};

function handleThemeChange(th) {
const theme = th;
console.log("theme...", theme);

if (["light", "vs-dark"].includes(theme.value)) {
setTheme(theme);
} else {
defineTheme(theme.value).then((_) => setTheme(theme));
}
}
useEffect(() => {
defineTheme("oceanic-next").then((_) =>
setTheme({ value: "oceanic-next", label: "Oceanic Next" })
);
}, []);

const showSuccessToast = (msg) => {


toast.success(msg || `Compiled Successfully!`, {
position: "top-right",
autoClose: 1000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,

66
draggable: true,
progress: undefined,
});
};
const showErrorToast = (msg, timer) => {
toast.error(msg || `Something went wrong! Please try again.`, {
position: "top-right",
autoClose: timer ? timer : 1000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
};

const [userDetails, setUserDetails] = useState(null);


const fetchUserData = async () => {
auth.onAuthStateChanged(async (user) => {
console.log(user);
const docRef = doc(db, "Users", user.uid);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
setUserDetails(docSnap.data());
console.log(docSnap.data());
} else {
console.log("User is not logged in");
}
});
};
useEffect(() => {
fetchUserData();
}, []);

return (
<div>
{userDetails?(
<>
<ToastContainer

67
position="top-right"
autoClose={2000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
/>

<div className="h-4 w-full bg-gradient-to-r from-pink-500 via-red-500 to-


yellow-500"></div>
<h1 className="flex justify-center">This is Online Compiler</h1>
<div className="flex flex-row">
<div className="px-4 py-2">
<LanguagesDropdown onSelectChange={onSelectChange} />
</div>
<div className="px-4 py-2">
<ThemeDropdown handleThemeChange={handleThemeChange} theme={theme} />
</div>
<div><button className="px-4 btn btn-primary mt-2 shadow-lg h-17"
onClick={()=>window.location.href="/profile"}>Click to view
profile</button></div>
</div>
<div className="flex flex-row space-x-4 items-start px-4 py-4">
<div className="flex flex-col w-full h-full justify-start items-end">
<CodeEditorWindow
code={code}
onChange={onChange}
language={language?.value}
theme={theme.value}
/>
</div>

<div className="right-container flex flex-shrink-0 w-[30%] flex-col">


<div className="flex flex-col items-end">
<CustomInput
customInput={customInput}
setCustomInput={setCustomInput}
/>

68
<OutputWindow outputDetails={outputDetails} />
<button
onClick={handleCompile}
disabled={!code}
className={classnames(
"mt-4 border-2 border-black z-10 rounded-md shadow-
[5px_5px_0px_0px_rgba(0,0,0)] px-4 py-2 hover:shadow transition duration-200 bg-
white flex-shrink-0",
!code ? "opacity-50" : ""
)}
>
{processing ? "Processing..." : "Compile and Execute"}
</button>
</div>
{outputDetails && <OutputDetails outputDetails={outputDetails} />}
</div>
</div>
<Footer />
</>
):(
<p>Loading...</p>
) }
</div>
);
};
export default Landing;

Login.js:
import { signInWithEmailAndPassword } from
"https://www.gstatic.com/firebasejs/10.11.0/firebase-auth.js";
import React, { useState } from "react";
import { auth } from "./Firebase";
import { toast } from "react-toastify";
import styles from './Login.module.css'
import avatar from '../assets/profile.png'

function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");

const handleSubmit = async (e) => {


e.preventDefault();
try {

69
await signInWithEmailAndPassword(auth, email, password);
console.log("User logged in Successfully");
alert("User logged in Successfully");
window.location.href = "/profile";
toast.success("User logged in Successfully", {
position: "top-center",
});
} catch (error) {
console.log(error.message);
alert(error.code);
toast.error(error.message, {
position: "bottom-center",
});
}
};

return (
<div className="container mx-auto">

{/* <Toaster position='top-center' reverseOrder={false}></Toaster> */}

<div className='flex justify-center items-center h-screen'>


<div className={styles.glass}>

<div className="title flex flex-col items-center">


<h4 className='text-4xl font-bold'>Hello Again!</h4>
<span className='py-1 text-xl w-2/3 text-center text-gray-500'>
</span>
</div>
<form onSubmit={handleSubmit}>
<h3 className="flex justify-center items-center text-gray-500">Login</h3>
<div className='profile flex justify-center py-4'>
<img src={avatar} className={styles.profile_img}
alt="avatar" />
</div>

<div className="mb-3">
<label>Email address</label>
<input
type="email"
className="form-control"
placeholder="Enter email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>

70
</div>

<div className="mb-3">
<label>Password</label>
<input
type="password"
className="form-control"
placeholder="Enter password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>

<div className=" flex justify-center ">


<button type="submit" className={styles.btn}>
Submit
</button>
</div>
<p className="forgot-password text-right">
New user <a href="/register">Register Here</a>
</p>
</form>
</div>
</div>
</div>
);
}

export default Login;

Register.js:
import { createUserWithEmailAndPassword } from
"https://www.gstatic.com/firebasejs/10.11.0/firebase-auth.js";
import React, { useState } from "react";
import { auth, db } from "./Firebase";
import { setDoc, doc } from "https://www.gstatic.com/firebasejs/10.11.0/firebase-
firestore.js";
import { toast } from "react-toastify";
import styles from './Register.module.css';

function Register() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");

71
const [fname, setFname] = useState("");
const [lname, setLname] = useState("");

const handleRegister = async (e) => {


e.preventDefault();
try {
await createUserWithEmailAndPassword(auth, email, password);
const user = auth.currentUser;
console.log(user);
if (user) {
await setDoc(doc(db, "Users", user.uid), {
email: user.email,
firstName: fname,
lastName: lname,
});
}
console.log("User Registered Successfully!!");
alert("User Registered Successfully!!");
toast.success("User Registered Successfully!!", {
position: "top-center",
});
} catch (error) {
console.log(error.message);
alert(error.code)
toast.error(error.message, {
position: "bottom-center",
});
}
};

return (
<div className="container mx-auto">

{/* <Toaster position='top-center' reverseOrder={false}></Toaster> */}

<div className='flex justify-center items-center h-screen'>


<div className={styles.glass}>

<div className="title flex flex-col items-center">


<h4 className='text-5xl font-bold'>Connect with us</h4>
{/* <span className='py-4 text-xl w-2/3 text-center text-gray-
500'>
Explore Us
</span> */}
</div>

72
<form onSubmit={handleRegister}>
<h3 className="flex justify-center items-center ">Sign Up</h3>

<div className="mb-3">
<label>First name</label>
<input
type="text"
className="form-control"
placeholder="First name"
onChange={(e) => setFname(e.target.value)}
required
/>
</div>

<div className="mb-3">
<label>Last name</label>
<input
type="text"
className="form-control"
placeholder="Last name"
onChange={(e) => setLname(e.target.value)}
/>
</div>

<div className="mb-3">
<label>Email address</label>
<input
type="email"
className="form-control"
placeholder="Enter email"
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>

<div className="mb-3">
<label>Password</label>
<input
type="password"
className="form-control"
placeholder="Enter password"
onChange={(e) => setPassword(e.target.value)}
required
/>
</div>

73
<div className="flex justify-center">
<button type="submit" className={styles.btn}>
Sign Up
</button>
</div>
<p className="forgot-password text-right">
Already registered <a href="/login">Login</a>
</p>
</form>
</div>
</div>
</div>
);
}
export default Register;

Profile.js:
import React, { useEffect, useState } from "react";
import { auth, db } from "./Firebase";
import { doc, getDoc } from "https://www.gstatic.com/firebasejs/10.11.0/firebase-
firestore.js";
import { toast } from "react-toastify";
import { Link } from "react-router-dom";
import styles from './Profile.module.css'
import {Toaster} from 'react-hot-toast'
import avatar from '../assets/profile.png'

function Profile() {
const [userDetails, setUserDetails] = useState(null);
const fetchUserData = async () => {
auth.onAuthStateChanged(async (user) => {
console.log(user);
const docRef = doc(db, "Users", user.uid);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
setUserDetails(docSnap.data());
console.log(docSnap.data());
} else {
console.log("User is not logged in");
}
});
};

74
useEffect(() => {
fetchUserData();
}, []);

async function handleLogout() {


try {
await auth.signOut();
window.location.href = "/login";
console.log("User logged out successfully!");
} catch (error) {
console.error("Error logging out:", error.message);
}
}
return (
<div>
{userDetails ? (
<>
<h3>Welcome {userDetails.firstName} 🙏🙏</h3>
<div>
<p>Email: {userDetails.email}</p>
<p>First Name: {userDetails.firstName}</p>
<p>Last Name: {userDetails.lastName}</p>
</div>
<div className="">
<button className="btn btn-primary m-5" onClick={handleLogout}>
Logout
</button>
<button className="btn btn-primary"
onClick={()=>window.location.href="/compiler"}>
Click to Code
</button>
</div>

</>
) : (
// <Navigate to={"/login"}/>
<p className="flex justify-center h-screen text-4xl">Loading...Account
might not registered</p>
)}
</div>
);
}
export default Profile;

75
OutputWindow.js:
import React from "react";

const OutputWindow = ({ outputDetails }) => {


const getOutput = () => {
let statusId = outputDetails?.status?.id;

if (statusId === 6) {
// compilation error
return (
<pre className="px-2 py-1 font-normal text-xs text-red-500">
{atob(outputDetails?.compile_output)}
</pre>
);
} else if (statusId === 3) {
return (
<pre className="px-2 py-1 font-normal text-xs text-green-500">
{atob(outputDetails.stdout) !== null
? `${atob(outputDetails.stdout)}`
: null}
</pre>
);
} else if (statusId === 5) {
return (
<pre className="px-2 py-1 font-normal text-xs text-red-500">
{`Time Limit Exceeded`}
</pre>
);
} else {
return (
<pre className="px-2 py-1 font-normal text-xs text-red-500">
{atob(outputDetails?.stderr)}
</pre>
);
}
};
return (
<>

<h1 className="font-bold text-xl bg-clip-text text-transparent bg-gradient-


to-r from-slate-900 to-slate-700 mb-2 text-left">
Output ↓
</h1>

76
<div className="w-full h-56 bg-[#1e293b] rounded-md text-white font-normal
text-sm overflow-y-auto">
{outputDetails ? <>{getOutput()}</> : null}
</div>
</>
);
};

export default OutputWindow;

App.js:
import "./App.css";
import { BrowserRouter, Route, Routes, Navigate } from "react-router-dom";
import LandingPage from "./pages/LandingPage";
import RegisterPage from "./pages/RegisterPage"
import LoginPage from "./pages/LoginPage";
import { ToastContainer } from "react-toastify";
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import Profile from './components/Profile'
import { auth } from "./components/Firebase";
import { useEffect,useState } from "react";

function App() {
const [user, setUser] = useState();
useEffect(() => {
auth.onAuthStateChanged((user) => {
setUser(user);
console.log(user)
});
});
return (
<BrowserRouter>
<Routes>
{/* <Route path="/" element={<LandingPage/>}></Route> */}
<Route
path="/"
element={user ? <Navigate to="/profile" /> : <LoginPage />}
/>
<Route path="/register" element={<RegisterPage/>}></Route>
<Route path="/login" element={<LoginPage/>}></Route>
<Route path="/profile" element={<Profile />} />
<Route path="/compiler" element={<LandingPage/>}/>
{/* <Route path="/user/compiler" element={<LandingPage/>}/> */}

77
</Routes>
</BrowserRouter>
);
}

export default App;

Custominput.js
import React from "react";
import { classnames } from "../utils/general";

const CustomInput = ({ customInput, setCustomInput }) => {


return (
<>
{" "}
<textarea
rows="5"
value={customInput}
onChange={(e) => setCustomInput(e.target.value)}
placeholder={`Custom input`}
className={classnames(
"focus:outline-none w-full border-2 border-black z-10 rounded-md
shadow-[5px_5px_0px_0px_rgba(0,0,0)] px-4 py-2 hover:shadow transition duration-
200 bg-white mt-2"
)}
></textarea>
</>
);
};

export default CustomInput;

Firebase.js:
import { initializeApp } from
"https://www.gstatic.com/firebasejs/10.11.0/firebase-app.js";
import {getAuth} from "https://www.gstatic.com/firebasejs/10.11.0/firebase-
auth.js";
import {getFirestore} from "https://www.gstatic.com/firebasejs/10.11.0/firebase-
firestore.js";

78
// import { initializeApp } from
"https://www.gstatic.com/firebasejs/10.11.0/firebase-app.js";
// import { getAuth } from "https://www.gstatic.com/firebasejs/10.11.0/firebase-
auth.js";
// import {getFirestore} from
"https://www.gstatic.com/firebasejs/10.11.0/firebase-firestore.js";

const firebaseConfig = {
apiKey: "AIzaSyBqlrJkflCK1PpJMxZf2Tk5_100FL7CcAA",
authDomain: "compiler-project-auth.firebaseapp.com",
projectId: "compiler-project-auth",
storageBucket: "compiler-project-auth.appspot.com",
messagingSenderId: "1080621152962",
appId: "1:1080621152962:web:12c93496caba63d9c4195b"
};

const app = initializeApp(firebaseConfig);

export const auth = getAuth();


export const db = getFirestore(app);
export default app;

Customstyles.js:
export const customStyles = {
control: (styles) => ({
...styles,
width: "100%",
maxWidth: "14rem",
minWidth: "12rem",
borderRadius: "5px",
color: "#000",
fontSize: "0.8rem",
lineHeight: "1.75rem",
backgroundColor: "#FFFFFF",
cursor: "pointer",
border: "2px solid #000000",
boxShadow: "5px 5px 0px 0px rgba(0,0,0);",
":hover": {
border: "2px solid #000000",
boxShadow: "none",
},
}),
option: (styles) => {
return {

79
...styles,
color: "#000",
fontSize: "0.8rem",
lineHeight: "1.75rem",
width: "100%",
background: "#fff",
":hover": {
backgroundColor: "rgb(243 244 246)",
color: "#000",
cursor: "pointer",
},
};
},
menu: (styles) => {
return {
...styles,
backgroundColor: "#fff",
maxWidth: "14rem",
border: "2px solid #000000",
borderRadius: "5px",
boxShadow: "5px 5px 0px 0px rgba(0,0,0);",
};
},

placeholder: (defaultStyles) => {


return {
...defaultStyles,
color: "#000",
fontSize: "0.8rem",
lineHeight: "1.75rem",
};
},
};

defineTheme.js:
import { loader } from "@monaco-editor/react";

const monacoThemes = {
active4d: "Active4D",
"all-hallows-eve": "All Hallows Eve",
amy: "Amy",
"birds-of-paradise": "Birds of Paradise",
blackboard: "Blackboard",

80
"brilliance-black": "Brilliance Black",
"brilliance-dull": "Brilliance Dull",
"chrome-devtools": "Chrome DevTools",
"clouds-midnight": "Clouds Midnight",
clouds: "Clouds",
cobalt: "Cobalt",
dawn: "Dawn",
dreamweaver: "Dreamweaver",
eiffel: "Eiffel",
"espresso-libre": "Espresso Libre",
github: "GitHub",
idle: "IDLE",
katzenmilch: "Katzenmilch",
"kuroir-theme": "Kuroir Theme",
lazy: "LAZY",
"magicwb--amiga-": "MagicWB (Amiga)",
"merbivore-soft": "Merbivore Soft",
merbivore: "Merbivore",
"monokai-bright": "Monokai Bright",
monokai: "Monokai",
"night-owl": "Night Owl",
"oceanic-next": "Oceanic Next",
"pastels-on-dark": "Pastels on Dark",
"slush-and-poppies": "Slush and Poppies",
"solarized-dark": "Solarized-dark",
"solarized-light": "Solarized-light",
spacecadet: "SpaceCadet",
sunburst: "Sunburst",
"textmate--mac-classic-": "Textmate (Mac Classic)",
"tomorrow-night-blue": "Tomorrow-Night-Blue",
"tomorrow-night-bright": "Tomorrow-Night-Bright",
"tomorrow-night-eighties": "Tomorrow-Night-Eighties",
"tomorrow-night": "Tomorrow-Night",
tomorrow: "Tomorrow",
twilight: "Twilight",
"upstream-sunburst": "Upstream Sunburst",
"vibrant-ink": "Vibrant Ink",
"xcode-default": "Xcode_default",
zenburnesque: "Zenburnesque",
iplastic: "iPlastic",
idlefingers: "idleFingers",
krtheme: "krTheme",
monoindustrial: "monoindustrial",
};

81
const defineTheme = (theme) => {
return new Promise((res) => {
Promise.all([
loader.init(),
import(`monaco-themes/themes/${monacoThemes[theme]}.json`),
]).then(([monaco, themeData]) => {
monaco.editor.defineTheme(theme, themeData);
res();
});
});
};

export { defineTheme };

CodeEditorWindow.js:
import React, { useState } from "react";

import Editor from "@monaco-editor/react";

const CodeEditorWindow = ({ onChange, language, code, theme }) => {


const [value, setValue] = useState(code || "");

const handleEditorChange = (value) => {


setValue(value);
onChange("code", value);
};

return (
<div className="overlay rounded-md overflow-hidden w-full h-full shadow-4xl">
<Editor
height="85vh"
width={`100%`}
language={language || "javascript"}
value={value}
theme={theme}
defaultValue="// some comment"
onChange={handleEditorChange}
/>
</div>
);
};
export default CodeEditorWindow;

82
LanguageDropDown.js:
import React from "react";
import Select from "react-select";
import { customStyles } from "../constants/customStyles";
import { languageOptions } from "../constants/languageOptions";

const LanguagesDropdown = ({ onSelectChange }) => {


return (
<Select
placeholder={`Filter By Category`}
options={languageOptions}
styles={customStyles}
defaultValue={languageOptions[0]}
onChange={(selectedOption) => onSelectChange(selectedOption)}
/>
);
};

export default LanguagesDropdown;

Index.css:
@import
url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@100;200;300;400;
500;600;700&display=swap');

@tailwind base;
@tailwind components;
@tailwind utilities;

* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'IBM Plex Sans', sans-serif;
font-weight: 300;
font-size: 14px;
background: #dcdce6;
background-image: url('./assets/Background.png');

83
}

.listItem:hover {
background: #e2e8f0;
cursor: pointer;
}

.github-corner svg {
position:absolute;
right:0;
top:0;
mix-blend-mode:darken;
color:#ffffff;
fill:#000000;
}
.github-corner:hover .octo-arm {
animation:octocat-wave .56s;
}
@keyframes octocat-wave {
0%, 100% {
transform:rotate(0);
}
20%, 60% {
transform:rotate(-20deg);

} 40%, 80% {
transform:rotate(10deg);
}
}

84
10 Conclusion And Features

The project is based on “Text Editor”. This software firm deals in developing software for its clients.

Text Editor: - A text editor is a type of program used for editing plain text files. A plain text file is
represented and edited by showing all the characters as they are present in the file. The only characters
usable for 'mark-up' are the control characters of the used character set; in practice this is newline, tab
and form etc.

As it is a competitive world and very fast world, every thing in the universes is to be internet. In this
internet world all the things are on-line. So we created software called “On-line java compiler with
security editor”.

85
Bibilography:
Text Book References:
 GRADY BOOCH, IVAR JACOBSON, JAMES RUMBAUGH, Unified Modeling
Language , 2nd edition , 2004.

 H.M. DEITEL & P.J . DEITEL , JAVA How to Program ,6th edition , 2005.

 ROGER S. PRESSMAN ,Software Engineering , A Practitioner’s Approach , 6th edition


, 2005.
 HERBERT SCHILDT , The Complete Reference JAVA , 5th edition, 2005.

Web References:
 www.ScienceDirect.com
 www.w3schools.com
 www.compilerworld.com
 https://www.freecodecamp.org/news/how-to-build-react-based-code-editor/
 https://judge0.com/
 https://rapidapi.com/

86

You might also like