DEV Community

Cover image for Revisiting DSA Through Mini Projects #2: HTML Syntax Validator
Amelia Dutta
Amelia Dutta Subscriber

Posted on

Revisiting DSA Through Mini Projects #2: HTML Syntax Validator

I am back with another mini project on revisiting DSA and today's topic is Stack! And how I built a simple HTML syntax checker app applying the Stack.

What is a Stack?

A stack is a collection of objects that are inserted and removed according to the Last-In,First-Out(LIFO) principle.

For example: Our Browser's Search history is an example of a stack where each time you visit a new web address, it will be pushed onto the stack of web addresses and by returning you are actually popping back the last searched address to the previously visited site!

Second Project of This Series: A HTML Syntax Checker
Before diving deeper into the project and the logic, check the app here: syntax-validator

Let's See How It Works

To check if HTML tags are balanced, we can use the LIFO property of a Stack. The logic is as follows:

  • Scan the Code: We read the HTML string from left to right.
  • Push Open Tags: Whenever we encounter an opening tag (like <div> or <p>) we push it onto our stack.
  • Pop Closing Tags: When we find a closing tag (like </div> or </p>) we check the top of our stack.
    • If the stack matches the current closing tag (e.g. top is div and current is /div) we pop it off. This means the tag was correctly closed!
    • If the stack is empty or the tags don't match, we know the syntax is invalid.
  • After reading the whole string if the stack is completely empty it means every opening tag had a matching closing tag and our html code is valid!

HTML syntax is valid

Implementation

I kept the implementation simple using vanilla JavaScript. Here is the snippet where the magic happens:

while(i != -1){
    // If it is an opening tag that means doesn't start with '/'
    if(!tag.startsWith("/")){
        stack.push(tag);
    }
    // If it is a Cclosing tag
    else{
        // Check if we have anything to close
        if(stack.length == 0){
            output.innerText = "Invalid Syntax";
            return;
        }
        // Check if it matches the last opened tag
        // Here tag.slice(1) removes the '/' so we compare "div" with "div"
        if(tag.slice(1) !== stack.pop()){
            output.innerText = "Invalid Syntax";
            return;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The key methods here are stack.push(tag) to add to our history of open tags and stack.pop() to match them when we close a tag.

Limitation

As I was revising stack and wanted to make a simple project on that topic so this project has some limitations:

  • Strict Matching: This code checks for exact string matches. That means <div class="hero-section"> wouldn't match </div> because the strings are different!
  • Empty Tags: HTML has "empty/void" tags like <img>, <br> and <hr> that don't need a closing tag. Which is why this code will return this as an Invalid Tag!

Invalid HTML syntax

This project made me realize that finding the right data structure is only half the battle. While the stack was the perfect tool for the core logic, I realized that a real-world solution must handle more complex issues, such as attributes and empty tags.

Top comments (0)