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

speakmaster-crl

v1.3.0

Published

Command Recognition Language

Downloads

219

Readme

Command Recognition Language (CRL)

Implementação da linguagem de reconhecimento de comandos, usada no SpeakMaster para a definição e estruturação de autômatos de comandos de voz.

Nessa linguagem, temos as seguintes funcionalidades:

  • Colchetes são usados para denotar termos opcionais que podem ou não ser falados:

    Termo opcional

  • Parênteses são usados para denotar uma lista de possíveis termos que podem ser falados:

    Lista de possíveis termos

  • Chaves são usadas para denotar variáveis que reconhecem qualquer sequência de termos da entrada:

    Variável

  • Além disso, é possível restringir o reconhecimento de variáveis adicionando uma lista de opções de termos à sua definição:

    Variável restringida a certos termos

Ao ser realizado o reconhecimento de uma dada entrada, os valores reconhecidos e associados as variáveis ficam disponíveis para acesso e utilização conforme demonstrado abaixo.

Como Usar

Dado o comando abaixo:

Comando para tocar uma música

O seguinte código é capaz de validar se uma dada entrada é ou não reconhecida por este comando:

const { Automata } = require("speakmaster-crl");

// Para definir um comando:
// Passe a definição do comando usando a linguagem CRL como parâmetro na criação de uma instância da classe Automata
const command = new Automata("play [[the] song] {SONG NAME} from [[the] {ALBUM TYPE (album, disc, record)}] {ALBUM}");

// Para verificar se uma entrada é reconhecida por um comando:
console.log(command.match("play where do we go from brave enough"));
/*Match {
	match: true,
	variables: {
		'SONG NAME': 'where do we go',
		ALBUM: 'brave enough',
		'ALBUM TYPE': ''
	},
	restrictedVariablesIndexes: { 'ALBUM TYPE': -1 },
	isBest: true
}*/

console.log(command.match("play the song where do we go from the record brave enough"));
/*Match {
	match: true,
	variables: {
		'SONG NAME': 'where do we go',
		ALBUM: 'brave enough',
		'ALBUM TYPE': 'record'
	},
	restrictedVariablesIndexes: { 'ALBUM TYPE': 2 },
	isBest: true
}*/

console.log(command.match("play where do we go"));
/*Match {
	match: false,
	variables: {},
	restrictedVariablesIndexes: {},
	isBest: false
}*/

// Para obter todas as possibilidades de comandos:
console.log(command.getAllPossibilities());
/*[
	'play {SONG NAME} from {ALBUM}',
	'play song {SONG NAME} from {ALBUM}',
	'play {SONG NAME} from album {ALBUM}',
	'play {SONG NAME} from disc {ALBUM}',
	'play {SONG NAME} from record {ALBUM}',
	'play the song {SONG NAME} from {ALBUM}',
	'play song {SONG NAME} from album {ALBUM}',
	'play song {SONG NAME} from disc {ALBUM}',
	'play song {SONG NAME} from record {ALBUM}',
	'play {SONG NAME} from the album {ALBUM}',
	'play {SONG NAME} from the disc {ALBUM}',
	'play {SONG NAME} from the record {ALBUM}',
	'play the song {SONG NAME} from album {ALBUM}',
	'play the song {SONG NAME} from disc {ALBUM}',
	'play the song {SONG NAME} from record {ALBUM}',
	'play song {SONG NAME} from the album {ALBUM}',
	'play song {SONG NAME} from the disc {ALBUM}',
	'play song {SONG NAME} from the record {ALBUM}',
	'play the song {SONG NAME} from the album {ALBUM}',
	'play the song {SONG NAME} from the disc {ALBUM}',
	'play the song {SONG NAME} from the record {ALBUM}'
]*/

// Para obter o comando de entrada do autômato:
console.log(command.command);
// play [[the] song] {SONG NAME} from [[the] {ALBUM TYPE (album, disc, record)}] {ALBUM}

Para obter informações sobre as variáveis do comando:

console.log(command.getVariablesNames());
// [ 'SONG NAME', 'ALBUM', 'ALBUM TYPE' ]

console.log(command.getRestrictedVariablesNames());
// [ 'ALBUM TYPE' ]

console.log(command.getUnrestrictedVariablesNames());
// [ 'SONG NAME', 'ALBUM' ]

console.log(command.getRestrictedVariableOptions("ALBUM TYPE"));
// [ 'album', 'disc', 'record' ]

// Passar uma variável irrestrita para a função getRestrictedVariableOptions irá retornar um vetor vazio
console.log(command.getRestrictedVariableOptions("SONG NAME"));
// []

console.log(command.getRestrictedVariableOptions("ALBUM"));
// []

Para controlar se a avaliação deve diferenciar letras maiúsculas e minúsculas:

// Case sensitive
console.log(command.match("PLAY Where Do We Go FROM Brave Enough", true));
/*Match {
	match: false,
	variables: {},
	restrictedVariablesIndexes: {},
	isBest: false
}*/

// Case insensitive
console.log(command.match("PLAY Where Do We Go FROM Brave Enough", false));
/*Match {
	match: true,
	variables: {
	  'SONG NAME': 'Where Do We Go',
	  ALBUM: 'Brave Enough',
	  'ALBUM TYPE': ''
	},
	restrictedVariablesIndexes: { 'ALBUM TYPE': -1 },
	isBest: true
}*/

// Case insensitive é o padrão
console.log(command.match("PLAY Where Do We Go FROM Brave Enough"));
/*Match {
	match: true,
	variables: {
	  'SONG NAME': 'Where Do We Go',
	  ALBUM: 'Brave Enough',
	  'ALBUM TYPE': ''
	},
	restrictedVariablesIndexes: { 'ALBUM TYPE': -1 },
	isBest: true
}*/

Para obter todos os reconhecimentos possíveis:

console.log(
	command.match("play the song where do we go from the record brave enough", false, true)
);
/*[
	Match {
		match: true,
		variables: {
			'SONG NAME': 'where do we go',
			ALBUM: 'brave enough',
			'ALBUM TYPE': 'record'
		},
		restrictedVariablesIndexes: { 'ALBUM TYPE': 2 },
		isBest: true
	},
	Match {
		match: true,
		variables: {
		'SONG NAME': 'where do we go',
		ALBUM: 'the record brave enough',
		'ALBUM TYPE': ''
		},
		restrictedVariablesIndexes: { 'ALBUM TYPE': -1 },
		isBest: false
	},
	Match {
		match: true,
		variables: {
			'SONG NAME': 'the song where do we go',
			ALBUM: 'brave enough',
			'ALBUM TYPE': 'record'
		},
		restrictedVariablesIndexes: { 'ALBUM TYPE': 2 },
		isBest: false
	},
	Match {
		match: true,
		variables: {
			'SONG NAME': 'the song where do we go',
			ALBUM: 'the record brave enough',
			'ALBUM TYPE': ''
		},
		restrictedVariablesIndexes: { 'ALBUM TYPE': -1 },
		isBest: false
	}
]*/

Para apenas validar a sintaxe de um comando:

const { validateSyntax } = require("speakmaster-crl");

const error = validateSyntax("play [the] song] {SONG NAME}");

console.log(error.message, { line: error.line, column: error.column });
// Unexpected lexeme "]" at 16 { line: 1, column: 16 }

Definição da gramática oficial no formato de Backus Naur Estendida (EBNF):

<sentence> ::= <sentence> <sentence>
               <term>
               '[' <optional> ']'
               '(' <list> ')'
               '{' <variable> '}'

<optional> ::= <optional> <optional>
               <term>
               '[' <optional> ']'
               '(' <list> ')'
               '{' <variable> '}'

<list>     ::= <item>
               <item> ',' <list>

<item>     ::= <item> <item>
               <term>
               '[' <optional> ']'
               '(' <list> ')'
               '{' <variable> '}'

<variable> ::= <string> { <string> } ['(' <list> ')']

<term>     ::= <string>

Estado inicial: <sentence>

Observação: uma <string> deve ser uma string contínua sem espaços.

Exemplo de Árvore de derivação

play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl [record])} called] {ALBUM}

Comando para tocar uma música

<sentence>
<sentence> <sentence>
<term> <sentence>
<string> <sentence>
play <sentence>
play <sentence> <sentence>
play [<optional>] <sentence>
play [<optional> <optional>] <sentence>
play [[<optional>] <optional>] <sentence>
play [[<optional> <optional>] <optional>] <sentence>
play [[<term> <optional>] <optional>] <sentence>
play [[<string> <optional>] <optional>] <sentence>
play [[the <optional>] <optional>] <sentence>
play [[the [<optional>]] <optional>] <sentence>
play [[the [<optional> <optional>]] <optional>] <sentence>
play [[the [<term> <optional>]] <optional>] <sentence>
play [[the [<string> <optional>]] <optional>] <sentence>
play [[the [really <optional>]] <optional>] <sentence>
play [[the [really <term>]] <optional>] <sentence>
play [[the [really <string>]] <optional>] <sentence>
play [[the [really awesome]] <optional>] <sentence>
play [[the [really awesome]] <term>] <sentence>
play [[the [really awesome]] <string>] <sentence>
play [[the [really awesome]] song] <sentence>
play [[the [really awesome]] song] <sentence> <sentence>
play [[the [really awesome]] song] {<variable>} <sentence>
play [[the [really awesome]] song] {<string> <string>} <sentence>
play [[the [really awesome]] song] {SONG <string>} <sentence>
play [[the [really awesome]] song] {SONG NAME} <sentence>
play [[the [really awesome]] song] {SONG NAME} <sentence> <sentence>
play [[the [really awesome]] song] {SONG NAME} <term> <sentence>
play [[the [really awesome]] song] {SONG NAME} <string> <sentence>
play [[the [really awesome]] song] {SONG NAME} from <sentence>
play [[the [really awesome]] song] {SONG NAME} from <sentence> <sentence>
play [[the [really awesome]] song] {SONG NAME} from [<optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [<optional> <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[<optional>] <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[<term>] <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[<string>] <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] <optional> <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {<variable>} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {<string> <string> (<list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM <string> (<list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (<list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (<item>, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (<term>, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (<string>, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, <item>, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, <item> <item>, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [<optional>] <item>, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [<term>] <item>, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [<string>] <item>, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] <item>, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] <term>, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] <string>, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, <list>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, <item>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, <item> <item>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, <term> <item>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, <string> <item>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great <item>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great <item> <item>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great <term> <item>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great <string> <item>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl <item>)} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl [<optional>])} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl [<term>])} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl [<string>])} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl [record])} <optional>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl [record])} <term>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl [record])} <string>] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl [record])} called] <sentence>
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl [record])} called] {<variable>}
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl [record])} called] {<string>}
play [[the [really awesome]] song] {SONG NAME} from [[the] {ALBUM TYPE (album, [blu-ray] disc, great vinyl [record])} called] {ALBUM}