Java代写:CSE214 JavaScript Formatter

代写一个JavaScript的格式化工具,考察Stack的运用。

Background

Famous programmer and open source activist Richard Stallman has often complained that code on the web is unreadable, and that it is impossible to determine its intentions by looking at it. In order to make javascript code (which is always accessible to a website’s user) fast and unreadable, developers use code obfuscators, which rename variables and remove whitespace. Minified and obfuscated code is often especially difficult to read because it appears in blocks. In order to help cranky old developers like Mr. Stallman read code, you will be writing a program that neatly formats javascript code.

Fortunately, JavaScript looks a lot like Java: its instructions are delimited by semicolons and its code blocks are delimited with curly braces. Your job will be to add new lines after each instruction, correctly indent the code, and make sure that curly braces and parentheses are closed in the correct order. By using a stack and a counter, you should also be able to determine the indentation level of the code, and determine if any parentheses and curly braces are missing, or in the wrong order. If you catch any code block or parentheses errors while neatly formatting your code, the program should stop and report the error to the user at the end of the now neatly formatted file.

How it works: Read through the JavaScript file character by character and copy it over to a new string. Every time you encounter a curly brace, or a semicolon (outside a for loop), add a newline character, as well as the correct number of tab characters to the new string. The number of tabs starts at 0. Every time you encounter an opening curly brace, add one to the number of tabs. Every time you encounter a closing curly brace, subtract one. Every time you encounter an opening curly brace, push the BRACE BlockType to the stack. Every time you encounter the opening parenthesis (that isn’t part of the for loop), push the PAREN BlockType to the stack. Every time you encounter the string “for(, push the FOR BlockType to the stack. Every time you encounter a closing curly brace or closing parenthesis, pop from the stack. If the item you popped does not match the type of closing character you encountered (or is empty), stop and print a new line explaining the problem. You do not need to continue to parse the rest of the file. Note: closing parenthesis matches both PAREN and FOR block types.

Your Task

Given an input javascript (.js) or text (.txt) file, you must format it as per the samples. This includes:

  • Adding newlines after ; and { and }
  • NOTE: you must not add newlines after ; iff the ; is in a for statement’s parentheses
  • Checking whether (, ), {, } are balanced (e.g. too many closing/openings, missing parentheses / braces)
  • Proper indentation depending on brace level
    • You can and should use a stack for those last two items
  • Input Note: Your input may have newlines and tabs already in it. They may not be correct.
    • Hint: it’s safest to remove all newlines and tabs before processing the file.

Error Checking

  • When you encounter any error, you stop going through the input there.
  • You are mainly formatting. You don’t need to concern yourself with something like for (;;;;;). You should detect something like console.log(500;, which is an error.
    • Rule: ; should never be inside () except when in for loop initialization. You do not need to format JS containing lambdas (if you don’t know what this is, don’t worry about it). Additionally, there will not be new opened braces or parentheses inside for loop initialization.
    • If you encounter something like 'foo("my string";', this would be a missing close parenthesis.
  • You need to print the error you encounter and write it to the end of the output file as a // comment. Examples: Missing close brace; Missing open brace, Missing close parenthesis, Missing open parenthesis, extra of any of those. You do not need to print the location (unless you’re doing extra credit).

Required Classes

JavascriptFormatterRunner (driver)

  • public static void main(String args)
    • Displays menu asking for name of input file
    • Rest of program flow follows the following use case:
    1. User is asked for a file name. Assume for example user enters ‘input.js’.
    2. File is read, and formatted internally.
    3. Program prints (to Standard Out) the formatted JavaScript from input and any errors. These errors also print to the console.
    4. Program Exits.

JavascriptFormatter

  • private JSStack stack - This is the stack where you will push and pop parentheses and braces.
  • private int indentLevel - This is where you store the number of tab (‘\t’) characters to print before a line
  • public String format(String input) - this method takes the data from the file and formats it.
  • public JavascriptFormatter() - constructor. Initialize your stack.

JSStack

You may choose to extend or use an existing stack, or implement your own (we suggest using a linked list type structure). This stack will be of BlockType objects. It would be good practice to implement your own.

If you use Java 1.8’s stack, you will likely want to read up on generics and this page. You do not need to use the provided name for the stack, but you must have a stack.

Your stack must have these public methods:

  • public void push(BlockType b) - pushes b onto the front of the backing data structure.
  • public BlockType pop() - takes the BlockType that is on top of the backing data structure, saves that value, removes that BlockType from the backing data structure, and returns that BlockType. If the stack was empty, throw an EmptyStackException.
  • public BlockType peek() - takes the BlockType that is on top of the backing data structure, and returns that value to the caller. Does NOT remove that BlockType from the backing data structure.
  • public boolean isEmpty() - returns true if stack is empty, false otherwise.

The details for these methods are standard stack methods. You can find those details in the lecture slides.

enum BlockType

  • BRACE
  • PAREN
  • FOR

General Recommendations

You might want to implement a toString() method for classes to make debugging and printing easier. You do not have to do this, but it will help you.

You can feel free to add any extra methods and variables as you see fit (public and private).