Skip to content

Commit

Permalink
Merge pull request #2 from nova-land/main
Browse files Browse the repository at this point in the history
Adding Literal Enum support.
  • Loading branch information
a10y committed Sep 30, 2023
2 parents 3f17b5c + b11b3ca commit 8ad1e8d
Show file tree
Hide file tree
Showing 7 changed files with 279 additions and 154 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ npm i --save @intrinsicai/gbnfgen
```typescript
import { compile, serializeGrammar } from "@intrinsicai/gbnfgen";

// Supporting Enum for multiple choices (cannot be numbers)
const grammar = compile(
`interface Person {
`enum Mood { Happy, Sad, Grateful, Excited, Angry, Peaceful }
interface Person {
name: string;
occupation: string;
age: number;
Expand Down
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"types": "dist/index.d.ts",
"scripts": {
"git-version": "npm version $(git describe --tags --always --first-parent)",
"exec": "tsc && node ./dist/grammarTest.js",
"test": "echo \"Error: no test specified\" && exit 1"
"build": "tsc",
"test": "vitest"
},
"type": "module",
"author": "Intrinsic Labs",
Expand Down
91 changes: 89 additions & 2 deletions src/compiler.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, test } from "vitest";
import { baseGrammar, compile } from "./compiler.js";
import { Grammar, reference, serializeGrammar } from "./grammar.js";
import { compile } from "./compiler.js";
import { serializeGrammar } from "./grammar.js";

test("Single interface generation", () => {
const postalAddressGrammar = compile(
Expand Down Expand Up @@ -28,6 +28,36 @@ numberlist ::= "[" ws "]" | "[" ws string ("," ws number)* ws
);
});

test("Single interface with enum generation", () => {
const postalAddressGrammar = compile(
`enum AddressType { business, home };
interface PostalAddress {
streetNumber: number;
type: AddressType;
street: string;
city: string;
state: string;
postalCode: number;
}`,
"PostalAddress"
);


expect(serializeGrammar(postalAddressGrammar).trimEnd()).toEqual(
String.raw`
root ::= PostalAddress
PostalAddress ::= "{" ws "\"streetNumber\":" ws number "," ws "\"type\":" ws enumAddressType "," ws "\"street\":" ws string "," ws "\"city\":" ws string "," ws "\"state\":" ws string "," ws "\"postalCode\":" ws number "}"
PostalAddresslist ::= "[]" | "[" ws PostalAddress ("," ws PostalAddress)* "]"
string ::= "\"" ([^"]*) "\""
boolean ::= "true" | "false"
ws ::= [ \t\n]*
number ::= [0-9]+ "."? [0-9]*
stringlist ::= "[" ws "]" | "[" ws string ("," ws string)* ws "]"
numberlist ::= "[" ws "]" | "[" ws string ("," ws number)* ws "]"
enumAddressType ::= "\"" "business" "\"" | "\"" "home" "\""`.trim()
)
});

test("Single multiple interface with references generation", () => {
const resumeGrammar = compile(
`
Expand Down Expand Up @@ -61,6 +91,63 @@ stringlist ::= "[" ws "]" | "[" ws string ("," ws string)* ws
numberlist ::= "[" ws "]" | "[" ws string ("," ws number)* ws "]"`);
});

test("Single multiple interface and enum with references generation", () => {
const resumeGrammar = compile(
`
// Define an enum for product categories
enum ProductCategory {
Electronics,
Clothing,
Food
}
// Define an interface for representing a product
interface Product {
id: number;
name: string;
description: string;
price: number;
category: ProductCategory;
}
// Define an enum for order statuses
enum OrderStatus {
Pending,
Shipped,
Delivered,
Canceled
}
// Define an interface for representing an order
interface Order {
orderId: number;
products: Product[];
status: OrderStatus;
orderDate: string;
}
`,
"Order"
);


expect(serializeGrammar(resumeGrammar).trimEnd()).toEqual(
String.raw`
root ::= Order
Order ::= "{" ws "\"orderId\":" ws number "," ws "\"products\":" ws Productlist "," ws "\"status\":" ws enumOrderStatus "," ws "\"orderDate\":" ws string "}"
Orderlist ::= "[]" | "[" ws Order ("," ws Order)* "]"
Product ::= "{" ws "\"id\":" ws number "," ws "\"name\":" ws string "," ws "\"description\":" ws string "," ws "\"price\":" ws number "," ws "\"category\":" ws enumProductCategory "}"
Productlist ::= "[]" | "[" ws Product ("," ws Product)* "]"
string ::= "\"" ([^"]*) "\""
boolean ::= "true" | "false"
ws ::= [ \t\n]*
number ::= [0-9]+ "."? [0-9]*
stringlist ::= "[" ws "]" | "[" ws string ("," ws string)* ws "]"
numberlist ::= "[" ws "]" | "[" ws string ("," ws number)* ws "]"
enumProductCategory ::= "\"" "Electronics" "\"" | "\"" "Clothing" "\"" | "\"" "Food" "\""
enumOrderStatus ::= "\"" "Pending" "\"" | "\"" "Shipped" "\"" | "\"" "Delivered" "\"" | "\"" "Canceled" "\""`.trim()
)
});

test("Jsonformer car example", () => {
const grammar = compile(
`
Expand Down

0 comments on commit 8ad1e8d

Please sign in to comment.