-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial commit (outputs valid/invalid file)
- Loading branch information
0 parents
commit 4a49527
Showing
24 changed files
with
485 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
*jp | ||
*algo.md | ||
|
||
|
||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
*.test | ||
|
||
# Vendor directory (for dependencies) | ||
vendor/ | ||
|
||
# Logs | ||
logs/ | ||
|
||
# IDE/editor specific files | ||
.vscode/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
build: | ||
go build -o jp main.go | ||
|
||
test: | ||
go build -o jp main.go && ./test.sh | ||
|
||
run: | ||
go run main.go demo.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
### JSON PARSER (from the coding challenges) | ||
|
||
- A JSON parser comprises mainly two parts: | ||
- **Lexical Analysis**: In this step, the input is converted into an array of tokens. | ||
- **Syntactic Analysis**: In this step, the tokens are parsed to check whether they align with the rules of the specified language. | ||
|
||
### Application Details | ||
|
||
- Currently, the software outputs whether the given JSON file is valid or not. | ||
- To test the application yourself, you can put your JSON content inside the `demo.json` file and run `make run`. It will tell you whether the content is valid JSON or not. | ||
- Additionally, there are plenty of test cases inside the `tests` directory. You can run them individually using the command `go run main.go relative-filepath`. | ||
- I have also prepared a bash script for running all the test cases inside the `tests` directory. You can run it using either the `./tests.sh` command, but first make sure you run `make build`. You can also run `make test` which is just an addition of these two commands. | ||
|
||
### Working of the Application | ||
|
||
- In the first step, the input file content is broken into an array of tokens. | ||
- In the next step, the tokens are cleaned up by trimming the whitespaces around them. | ||
- The tokens are then passed into a parser function that parses the tokens to see if they align with the specified language rules. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
[ | ||
{ | ||
"id": "0001", | ||
"type": "donut", | ||
"name": "Cake", | ||
"ppu": 0.55, | ||
"batters": | ||
{ | ||
"batter": | ||
[ | ||
{ "id": "1001", "type": "Regular" }, | ||
{ "id": "1002", "type": "Chocolate" }, | ||
{ "id": "1003", "type": "Blueberry" }, | ||
{ "id": "1004", "type": "Devil's Food" } | ||
] | ||
}, | ||
"topping": | ||
[ | ||
{ "id": "5001", "type": "None" }, | ||
{ "id": "5002", "type": "Glazed" }, | ||
{ "id": "5005", "type": "Sugar" }, | ||
{ "id": "5007", "type": "Powdered Sugar" }, | ||
{ "id": "5006", "type": "Chocolate with Sprinkles" }, | ||
{ "id": "5003", "type": "Chocolate" }, | ||
{ "id": "5004", "type": "Maple" } | ||
] | ||
}, | ||
{ | ||
"id": "0002", | ||
"type": "donut", | ||
"name": "Raised", | ||
"ppu": 0.55, | ||
"batters": | ||
{ | ||
"batter": | ||
[ | ||
{ "id": "1001", "type": "Regular" } | ||
] | ||
}, | ||
"topping": | ||
[ | ||
{ "id": "5001", "type": "None" }, | ||
{ "id": "5002", "type": "Glazed" }, | ||
{ "id": "5005", "type": "Sugar" }, | ||
{ "id": "5003", "type": "Chocolate" }, | ||
{ "id": "5004", "type": "Maple" } | ||
] | ||
}, | ||
{ | ||
"id": "0003", | ||
"type": "donut", | ||
"name": "Old Fashioned", | ||
"ppu": 0.55, | ||
"batters": | ||
{ | ||
"batter": | ||
[ | ||
{ "id": "1001", "type": "Regular" }, | ||
{ "id": "1002", "type": "Chocolate" } | ||
] | ||
}, | ||
"topping": | ||
[ | ||
{ "id": "5001", "type": "None" }, | ||
{ "id": "5002", "type": "Glazed" }, | ||
{ "id": "5003", "type": "Chocolate" }, | ||
{ "id": "5004", "type": "Maple" } | ||
] | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module github.com/melsonic/json-parser | ||
|
||
go 1.21.6 | ||
|
||
require github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4= | ||
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package main | ||
|
||
// _ | ||
// (_)___ ___ _ __ _ __ __ _ _ __ ___ ___ _ __ | ||
// | / __|/ _ \| '_ \ _____| '_ \ / _` | '__/ __|/ _ \ '__| | ||
// | \__ \ (_) | | | |_____| |_) | (_| | | \__ \ __/ | | ||
// _/ |___/\___/|_| |_| | .__/ \__,_|_| |___/\___|_| | ||
// |__/ |_| | ||
// | ||
|
||
import ( | ||
"log" | ||
"os" | ||
|
||
"github.com/melsonic/json-parser/util" | ||
) | ||
|
||
func main() { | ||
var result bool = false | ||
jsonFileName := os.Args[1] | ||
content, err := os.ReadFile(jsonFileName) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
result = util.Validate(content) | ||
util.PrintResult(result) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#!/bin/bash | ||
|
||
for file in tests/* | ||
do | ||
if [ -d $file ] | ||
then | ||
for rfile in $file/* | ||
do | ||
echo "$rfile" | ||
./jp $rfile | ||
echo "" | ||
done | ||
else | ||
echo "$file" | ||
./jp $file | ||
echo "" | ||
fi | ||
done | ||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"key": "value",} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"key": "value", | ||
key2: "value" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"key": "value"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"key": "value", | ||
"key2": "value" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"key1": true, | ||
"key2": False, | ||
"key3": null, | ||
"key4": "value", | ||
"key5": 101 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"key1": true, | ||
"key2": false, | ||
"key3": null, | ||
"key4": "value", | ||
"key5": 101 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"key": "value", | ||
"key-n": 101, | ||
"key-o": { | ||
"inner key": "inner value" | ||
}, | ||
"key-l": ['list value'] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"key": "value", | ||
"key-n": 101, | ||
"key-o": {}, | ||
"key-l": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"key": "value", | ||
"key-n": 101, | ||
"key-o": { | ||
"inner key": "inner value" | ||
}, | ||
"key-l": ["list value"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package util | ||
|
||
var ( | ||
EmptyLineByte byte = byte('\n') | ||
WhiteSpaceByte byte = byte(' ') | ||
ColonByte byte = byte(':') | ||
CommaByte byte = byte(',') | ||
LeftCurlyBraceByte byte = byte('{') | ||
RightCurlyBraceByte byte = byte('}') | ||
LeftSquareBracketByte byte = byte('[') | ||
RightSquareBracketByte byte = byte(']') | ||
DoubleQuoteByte byte = byte('"') | ||
BackSlashByte byte = byte('\\') | ||
ForwardSlashByte byte = byte('/') | ||
) | ||
|
||
var ( | ||
LeftCurlyBrace string = "{" | ||
RightCurlyBrace string = "}" | ||
LeftSquareBrace string = "[" | ||
RightSquareBrace string = "]" | ||
Comma string = "," | ||
Colon string = ":" | ||
DoubleQuote string = "\"" | ||
) | ||
|
||
var BackSlashRune rune = rune('\\') | ||
|
||
var ( | ||
CheckSlice = []byte{LeftCurlyBraceByte, LeftSquareBracketByte, ColonByte, CommaByte, RightSquareBracketByte, RightCurlyBraceByte} | ||
AllowedCharsAfterEscapeChar = []rune{'"', '\\', '/', 'b', 'f', 'n', 'r', 't'} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package util | ||
|
||
func Lexer(content []byte) []string { | ||
var isInsideString bool = false | ||
var prevByte byte | ||
var currBytes []byte | ||
var lexResult []string | ||
for _, byt := range content { | ||
if byt != DoubleQuoteByte || prevByte == BackSlashByte { | ||
if isInsideString { | ||
currBytes = append(currBytes, byt) | ||
} else { | ||
var present bool = false | ||
for _, cs := range CheckSlice { | ||
if cs == byt { | ||
present = true | ||
break | ||
} | ||
} | ||
if present { | ||
if len(currBytes) > 0 { | ||
lexResult = append(lexResult, string(currBytes)) | ||
currBytes = nil | ||
} | ||
lexResult = append(lexResult, string(byt)) | ||
} else { | ||
currBytes = append(currBytes, byt) | ||
} | ||
} | ||
} else { | ||
currBytes = append(currBytes, byt) | ||
if isInsideString { | ||
lexResult = append(lexResult, string(currBytes)) | ||
currBytes = nil | ||
} | ||
isInsideString = !isInsideString | ||
} | ||
prevByte = byt | ||
} | ||
return lexResult | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package util | ||
|
||
func Parser(lexToken []string) ([]string, bool) { | ||
var result bool = false | ||
token := lexToken[0] | ||
if token == LeftCurlyBrace { | ||
lexToken = lexToken[1:] | ||
lexToken, result = IsValidObject(lexToken) | ||
} else if token == LeftSquareBrace { | ||
lexToken = lexToken[1:] | ||
lexToken, result = IsValidArray(lexToken) | ||
} else { | ||
result = IsValidString(token) || IsValidNumber(token) || IsValidBoolean(token) || IsValidNull(token) | ||
lexToken = lexToken[1:] | ||
} | ||
return lexToken, result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package util | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
) | ||
|
||
// entry function for validator | ||
func Validate(content []byte) bool { | ||
var result bool = false | ||
var lexToken []string = Lexer(content) | ||
lexToken = CleanUp(lexToken) | ||
_, result = Parser(lexToken) | ||
return result | ||
} | ||
|
||
// clean up the spaces around the braces | ||
func CleanUp(lexToken []string) []string { | ||
lenLexToken := len(lexToken) | ||
var trimmedLexToken []string | ||
for i := 0; i < lenLexToken; i++ { | ||
tempStr := strings.TrimSpace(lexToken[i]) | ||
if tempStr != "" { | ||
trimmedLexToken = append(trimmedLexToken, tempStr) | ||
} | ||
} | ||
return trimmedLexToken | ||
} | ||
|
||
func PrintResult(result bool) { | ||
if result { | ||
fmt.Printf("The file is a valid\n") | ||
} else { | ||
fmt.Printf("The file is invalid\n") | ||
} | ||
} |
Oops, something went wrong.