npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@gobstones/gobstones-gbb-parser

v0.4.3

Published

A Parser/Stringifier for GBB (Gobstones Board) file format

Downloads

35

Readme

gobstones-gbb-parser

A Gobstones Board Parser and Stringifier.

Licence Version API Docs

GitHub Workflow Tests GitHub Workflow Build

Gobstones Board Language Specification

The Gobstones Board Language is a declarative language for specifying boards for the Gobstones Language. The language follows the following EBNF spec:

Main ->	FormatDeclaration __
        SizeDeclaration __
        (CellDeclarationList __)?
        (HeadDeclaration)?
        __?

FormatDeclaration   ->  "GBB/1.0"
                    |   "GBB"
                    |   "gbb"

SizeDeclaration     ->  "size" _ Number _ Number

HeadDeclaration     ->  "head" _ Number _ Number

CellDeclarationList ->  CellDeclaration
                    |   CellDeclaration __ CellDeclarationList

CellDeclaration     ->  "cell" _ Number _ Number _ StonesDefinition

StonesDefinition    ->  SingleStoneDefinition
                    |   SingleStoneDefinition __ StonesDefinition

SingleStoneDefinition   ->  ("Azul"|"A"|"a")  _ Number
                        |   ("Negro"|"N"|"n") _ Number
                        |   ("Rojo"|"R"|"r")  _ Number
                        |   ("Verde"|"V"|"v") _ Number

Number -> [0-9]+
_ -> [ \t]+
__ -> [ \t\n\v\f]+

Here is a simple example of a Gobstones Board definition:

GBB/1.0
size 3 4
cell 2 1 a 1
cell 1 2 n 1 r 3
cell 3 1 r 2 a 1
head 1 1

So to break it down in simple words. A Gobstones Board Definition:

  • Must start with the format declaration at first line ("GBB/1.0")
  • Must be followed by a size declaration of the form "size "
  • May contain any number of cell declarations "cell " followed by stone amount definitions in the form " "
  • May end with a head declaration in the form "head ".

Where:

  • is a positive non zero number.
  • is a positive non zero number.
  • is a positive zero based coordinate such that <
  • is a positive zero based coordinate such that <
  • is a positive or zero number
  • is any of:
    • "Azul" (which may also be refered as "A" or "a")
    • "Negro" (which may also be refered as "N" or "n")
    • "Rojo" (which may also be refered as "R" or "r")
    • "Verde" (which may also be refered as "V" or "v")
  • Blanks are important in the language, and numbers and keywords should be separated by a space or tab.
  • Each line definition must be separated by a blank, whether is a space, a tab or line feed character.

Some additional considerations include:

  • There cannot be two cell definitions for the same cell.
  • There cannot be two definitions for the same color in the same cell
  • There can be any amount of blank lines at the end of the file

Gobstones Board Output/Input

The parsed result produced/consumed by the parser is a Board as the one exported by gobstones-core. We recommend to check it's API in order to better understand the object and all it's associated methods. To sum up, it's a TypeScript/JavaScript object that has the Board type. where:

type Board = {
    width: number;          // width of the board
    height: number;         // height of the board
    head: [number, number]; // array [x, y] with the position of the head
    getColumns(): Cell[][]; // array of <width> elements,
                            // each of which is an array of <height> elements,
                            // each of which is a Cell
};
type Cell = {
    x: number;              // The cell's x location
    y: number;              // The cell's x location
    getStonesOf(color: Color): number;   // Returns the amount of stones
                            // for the given color.
}

Parsing may also produce errors which live in the GBBParsingErrors namespace (when parsing) or GBBStringifyingErrors (when stringifying).

When parsing a given string for a GBB definition you may find:

GBBParsingErrors.UnexpectedToken           // If an invalid token is found in the string,
GBBParsingErrors.UnexpectedEOF             // If the EOF is reached but a valid board could not yet be produced.
GBBParsingErrors.InvalidSizeDefinition     // If the size is zero in any of their components.
GBBParsingErrors.HeadBoundaryExceeded      // If the head position exceeds the size of the board.
GBBParsingErrors.DuplicatedCellDefinition  // If there is more than one definition for the same cell.
GBBParsingErrors.DuplicatedColorDefinition // If there is more than one definition for the same color in any given cell.
GBBParsingErrors.CellBoundaryExceeded     // If for any given cell declaration the coordinates exceeds the size of the board.

These all inherit from GBBParsingErrors.GBBParsingError.

Unparsing on the other hand may produce similar errors if the provided object contains errors that makes it an invalid board. These include:

GBBStringifyingErrors.InvalidSizeDefinition       // If the size is zero or negative in any of their components.
GBBStringifyingErrors.HeadBoundaryExceeded        // If the head position exceeds the size of the board.
GBBStringifyingErrors.InvalidCellDefinition       // If the data for the stones in a cell are incomplete or contains more info than needed.
GBBStringifyingErrors.InvalidBoardDefinition      // If the board information provided does not match width and height of the board.

This all inherit from GBBStringifyingErrors.GBBStringifyingError.

Translations

Error messages are translated to the user desired language, although this does not change the language definition in any way. See below on how to translate error messages to a given language.

Installing

To install run

npm install @gobstones/gobstones-gbb-parser

or if you are using yarn.

yarn add @gobstones/gobstones-gbb-parser

Usage as a module

Import GBB from the module and parse a string defining a Gobstones Board.

import { GBB } from '@gobstones/gobstones-gbb-parser';

const myBoard = "GBB/1.0 size 3 4 cell 2 1 a 1 cell 1 2 n 1 r 3 cell 1 3 r 2 a 1 head 1 1";

const BoardObject = GBB.parse(myBoard);

console.log(BoardObject)

The output of the parser is a JSON output with the aforementioned spec. You could also pass the object representing a Board and produce a GBB string by calling stringify, as follows:

import { GBB } from '@gobstones/gobstones-gbb-parser';
import { Board, Color } from '@gobstones/gobstones-core';

const myBoard = new Board(3, 4, [1, 1], [
    {x: 2, y: 1, [Color.Black]: 1, [Color.Red]: 3},
    {x: 3, y: 1, [Color.Blue]: 1, [Color.Red]: 3},
]);

const GBBBoardString = GBB.stringify(myBoard);

console.log(GBBBoardString)

Additionally, you can pass an object that it's not a board, but has all it's properties, this is the expected behavior when working from the CLI:

import { GBB } from '@gobstones/gobstones-gbb-parser';

const myBoard = {
    x: 3,
    y: 4,
    head: [1, 1],
    cellData: [
        {x: 2, y: 1, [Color.Black]: 1, [Color.Red]: 3},
        {x: 3, y: 1, [Color.Blue]: 1, [Color.Red]: 3},
    ]
};

const GBBBoardString = GBB.stringify(myBoard);

console.log(GBBBoardString)

Passing options

You can pass an object of type GBBParsingOptions to parse to specify additional options as a second argument.

interface GBBParsingOptions = {
    /** The error message output language */
    language: Locale;
}

Whereas for stringify you can pass a GBBStringifyingOptions as a second argument.

interface GBBStringifyingOptions {
    /** The error message output language */
    language: Locale;
    /** Different separator options */
    separators: {
        /** The separator to use between each language keyword.
         * Defaults to 'newline' */
        betweenKeywords: WhiteWithNewlineOption;
        /** The separator to use between different color names in the same line.
         * Defaults to 'space' */
        betweenColors: WhiteOption;
        /** The separator to use between a color name and the number that follows.
         * Defaults to 'tab' */
        colorKeyToNumber: WhiteOption;
        /** The separator to use between different elements of a coordinate.
         * Defaults to 'space' */
        betweenCoordinates: WhiteOption;
        /** The separator to use between the keyword and the first element of a coordinate.
         * Defaults to 'space' */
        keywordToCoordinates: WhiteOption;
    };
    /** Use the full color name in output. Defaults to 'true' */
    useFullColorNames: boolean;
    /** Maintain the color key for colors which have zero stone for cells
     * which have at least one stone. Defaults to 'false' */
    declareColorsWithZeroStones: boolean;
    /** Maintain the color key for colors which have zero stone for cells
     * even for cells that have no stones at all. This indeed produces a
     * 'cell' line for each cell of the board, which is not desirable for
     * large board. Defaults to 'false' */
    declareColorsWithAllZeroStones: boolean;
}

type WhiteOption = 'space' | 'tab';
type WhiteWithNewlineOption = 'space' | 'tab' | 'newline';

where you can configure the produced output string when unparsing, but specifying different separator symbols, choose to use full color names or short names, and maintain or remove empty color names and cells.

Available locales are currently en and es, and defaults to 'en'.

type Locale = 'en' | 'es'; // Defaults to 'en'.

Usage as CLI

This module installs a gobstones-gbb-parser command in the NPM bin folder. You can use the parser from the command line. If you want to use it from anywhere on your machine, install the module globally with:

npm install --global @gobstones/gobstones-gbb-parser

Then you can call the parser with the version option to check the currently installed version.

gobstones-gbb-parser --version

Use help to chek available commands.

gobstones-gbb-parser --help

Modifying and compiling

If you want to modify the code, just download the project with git

git clone https://github.com/gobstones/gobstones-gbb-parser
cd gobstones-gbb-parser

You may compile the project with

npm start build

which produces the output in the dist directory.

If you want to run the tests, run

npm test

Minimal source code guide

The project structre is as follows:

src
 |- grammar       // Lexer and Parser definitions
 |- parser        // Parsing functions, models and error definitions
 |- stringifier   // Stringify functions, models and error definitions
 |- helpers       // Helper functions and definitions
 |- translations  // JSON files containing translation strings
 |- models.ts     // The exported types for the module
 |- models.ts     // Some defaults the module exports
 |- index.ts      // The main exported module, including the GBB object
 |- cli.ts        // The CLI definition

The project uses mainly a lexer/tokenizer written using moo that you can find in src/grammar/gbb-lexer.js and a parser generated by nearley parser, whose spec you may find in src/grammar/gbb-grammar.ne. The code in that file is mostly self explanatory and follows the EBNF spec of the language, with additional code used by nearley to produce an intermediate output.

The output of the grammar produces an intermediate AST which is managed by src/parser/parser.ts. This files exports the parse function, that validates the consistency of data and produces a ready for interpreter consumption object.

On the other hand src/stringifier/stringifier.ts exports the stringify function, that takes an object and produces a GBB format string.

Other files include the definition of types for Board, CellInfo and other utilities, as well as errors for parse and stringify.

Everything is then wrapped up by the src/index.js file that exports all defined types and a GBB object which the aforementioned functions parse and stringify, types, and defaults.