Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Dependencies
node_modules

# Build outputs
dist
build

# Generated files
*.min.js
*.min.css

# Config files
package-lock.json
pnpm-lock.yaml
yarn.lock
10 changes: 10 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"plugins": ["prettier-plugin-tailwindcss"],
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": false,
"jsxSingleQuote": false,
"trailingComma": "es5",
"arrowParens": "always"
}
96 changes: 36 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,73 +1,49 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
# Expression Compiler (React + TypeScript)

Currently, two official plugins are available:
This project is a simple expression compiler built for a university compiler course. It demonstrates the main stages of compilation for mathematical expressions:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
- **Lexical Analysis**: Tokenizes the input string (identifiers, numbers, operators, parentheses, functions).
- **Parsing**: Builds an Abstract Syntax Tree (AST) from the token stream.
- **AST Visualization**: Shows the parse tree using a graphical tree view.
- **Code Generation**: Produces three-address code (TAC) from the AST.

## React Compiler
## Features

The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
- Input and validate math expressions (supports variables, numbers, +, -, *, /, ^, parentheses, and `sqrt` function).
- See the token list, transformed expression, parse tree, and generated TAC.
- All logic is implemented in TypeScript and React.
- Visualizes the parse tree using `react-d3-tree`.
- Styled with Tailwind CSS.

## Expanding the ESLint configuration
## Main Packages Used

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
- [React](https://react.dev/) — UI framework
- [Vite](https://vitejs.dev/) — build tool and dev server
- [Tailwind CSS](https://tailwindcss.com/) — utility-first CSS framework
- [react-d3-tree](https://github.com/bkrem/react-d3-tree) — parse tree visualization

```js
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
## Getting Started

// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
1. Install dependencies:
```bash
npm install
```
2. Start the development server:
```bash
npm run dev
```
3. Open [http://localhost:5173](http://localhost:5173) in your browser.

// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```
## Project Structure

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
- `src/utils/lexer.ts` — Lexer (tokenizer)
- `src/utils/parser.ts` — Parser and AST builder
- `src/utils/codegen.ts` — Three-address code generator
- `src/components/InputForm.tsx` — Main input and analysis UI
- `src/components/TreeView.tsx` — Parse tree visualization
- `src/App.tsx` — App layout and stage display

```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
---

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```
This project is for educational purposes and demonstrates the basic steps of compiling and visualizing simple math expressions in a web app.
23 changes: 0 additions & 23 deletions eslint.config.js

This file was deleted.

91 changes: 91 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import reactPlugin from "eslint-plugin-react";
import reactHooksPlugin from "eslint-plugin-react-hooks";
import reactRefreshPlugin from "eslint-plugin-react-refresh";
import importPlugin from "eslint-plugin-import";
import globals from "globals";

const eslintConfig = [
{ ignores: ["dist", "node_modules", "build", "*.config.js"] },
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ["**/*.{ts,tsx,js,jsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: {
ecmaVersion: "latest",
ecmaFeatures: { jsx: true },
sourceType: "module",
},
},
settings: {
react: { version: "detect" },
},
plugins: {
react: reactPlugin,
"react-hooks": reactHooksPlugin,
"react-refresh": reactRefreshPlugin,
import: importPlugin,
},
rules: {
// React rules
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",

// React Hooks rules
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",

// React Refresh
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],

// TypeScript rules
"@typescript-eslint/no-unused-vars": [
"warn",
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
],

// Import ordering
"import/order": [
"error",
{
groups: [
"builtin",
"external",
"internal",
["parent", "sibling"],
"index",
"object",
"type",
],
"newlines-between": "always",
pathGroups: [
{
pattern: "react",
group: "external",
position: "before",
},
{
pattern: "@/**",
group: "internal",
position: "after",
},
],
pathGroupsExcludedImportTypes: ["react"],
alphabetize: {
order: "asc",
caseInsensitive: true,
},
},
],
},
},
];

export default eslintConfig;
10 changes: 8 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap"
rel="stylesheet"
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>expression-compiler</title>
<title>Expression Compiler</title>
</head>
<body>
<div id="root"></div>
Expand Down
Loading