brandonhorst / elliptical Goto Github PK
View Code? Open in Web Editor NEWInteractive natural language parsing library in Javascript
Home Page: http://elliptical.laconalabs.com/
License: Apache License 2.0
Interactive natural language parsing library in Javascript
Home Page: http://elliptical.laconalabs.com/
License: Apache License 2.0
I was trying to understand how elliptical is working under the hood.
There are almost no comments in source code.
Is it possible for you to describe what is happening when grammar is compiled, and how traversing
is working here?
I think it could also unblock it a bit to be improved by community including myself :)
It would be nice to have a list of all the commands.
I'd be willing to create all the Wiki pages if the was a list.
I'll start with the ones on the hompage for now, but a please send me a list.
lacona looks cool but the basic usage example seems need some react knowledge to execute the script.
First, the script need both lacona, lacona-parse,
npm install lacona lacona-parse
then it need some tooling like (babel-cli, transform-react-jsx plugin) to execute the script
npm install babel-cli transform-react-jsx
Running command
babel --optional runtime --stage 0 --plugins transform-react-jsx main.jsx > main.js
can translate jsx to dom-like syntax, but I still got error with lacona
<project folder>/node_modules/lacona/lib/parser.js:61
throw _iteratorError;
^
Error
at Object.<anonymous> (/home/gasolin/Document/laca/node_modules/lacona/lib/error.js:12:25)
at Module._compile (module.js:435:26)
at Object.Module._extensions..js (module.js:442:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)
at Module.require (module.js:366:17)
at require (module.js:385:17)
at Object.<anonymous> (/home/gasolin/Document/laca/node_modules/lacona/lib/descriptor.js:28:14)
at Module._compile (module.js:435:26)
at Object.Module._extensions..js (module.js:442:10)
It will be helpful to setup a bare-bone example (or a sample repo), so people who is new to those tooling can try lacona with less burden.
When I follow the link: http://elliptical.laconalabs.com/
I get error 1014 CNAME Cross-User Banned
Currently I'm hosting a Browserified version of this library on my server. It would be nice at some point to submit it an "official" browser-ready version to JSDeliver CDN, so it can be lazily loaded by web pages using it.
Thanks for this library.
Really want to try it out, but I just can't get any examples working.
I've tried the first code example in the README.md file:
...
// Build our grammar out of Elements
const grammar = (
<sequence>
<literal text='flights ' />
<choice id='direction'>
<literal text=' from ' value='from' />
<literal text=' to ' value='to' />
</choice>
<Country id='country' />
</sequence>
)
// Obtain a parse function from our grammar
const parse = compile(grammar)
// Parse based upon a given query
const outputs = parse('flights to irela')
console.log(outputs)
but the outputs
variable is always []
.
I've double checked things, and tried other examples, but it is always []
that is returned.
Any advice would be gratefully received.
The Constructor is null hence it fails.
function getRealProps(_ref2) {
var descriptor = _ref2.descriptor;
var Constructor = _ref2.Constructor;
var realProps = _lodash2['default'].defaults(descriptor.props || {}, Constructor.defaultProps || {}); //FAILING LINE
if (descriptor.children && descriptor.children.length > 0) {
realProps.children = _lodash2['default'].flattenDeep(descriptor.children);
}
return realProps;
}
I cannot make this work (still.)
here is my test code:
var lacona = require('./lib/lacona.js');
var parser = new lacona.Parser();
var grammar = {
"root": {
"type": "choice",
"children": [
"remind me to",
{ "type": "freetext", "id": "taskName" }
]
}
};
parser.understand(grammar);
parser.on('data', function (result){
console.log(result)
});
parser.on('end', function (result) {
console.log(result)
});
parser.parse('remind me to poop')
it only returns "undefined"
suggestions?
I am not able to find my brew cask installed apps with Lacona.
Here is the equivalent of this issue on brew cask's repo in relation to alfred caskroom/homebrew-cask Installed apps can't be found by Alfred (issue #4327)
I guess an mvp of this would be some way to add path's to lacona's indexing scope, that way you don't solve the problem of apps installed via cask brew not showing up out of the box, but you potentially let others find out which path's they would include by default.
Currently I'm hosting a Browserified version of this library on my server. It would be nice at some point to submit it an "official" browser-ready version to JSDeliver CDN, so it can be lazily loaded by web pages using it.
Hola! @agustifernandez has created a ZenHub account for the lacona organization. ZenHub is the leading team collaboration and project management solution built for GitHub.
To get set up with ZenHub, all you have to do is download the browser extension and log in with your GitHub account. Once you do, you’ll get access to ZenHub’s complete feature-set immediately.
ZenHub adds a series of enhancements directly inside the GitHub UI:
Still curious? See more ZenHub features or read user reviews. This issue was written by your friendly ZenHub bot, posted by request from @agustifernandez.
All Lacona phrases are made out of the 4 fundamental phrases: choice
, sequence
, repeat
, and value
.
Almost all phrases will be composed of other phrases built on top of these basic 4. The included literal
phrase, for example, is itself composed of a single value
phrase. Other phrases can themselves contain literal
phrases. And other phrases can contain those.
This presents interesting versioning problems. Different versions of phrases could have unique interfaces (with different major versions of course!), so phrases be able to rely on using the versions that they specify.
Ideas:
Lacona dynamically requires packages by reading the package.json
files of dependencies, using resolve-recurse.
Each phrase contains its own dependencies with a require statement. Any references to phrases will check the dependencies
first. Something like:
{
name: 'timer',
dependencies: [
require('lacona-phrase-number'),
require('lacona-phrase-date')
]
}
Each phrase lists its own dependencies, but only one phrase can be loaded per name
module.exports
doesn't contain the version, so there isn't even any way to "use the latest version" - it would need to just either use the first or last one understand
'd.Phrases list their dependencies somehow (maybe package.json), but nothing is done with them. They must be individually understand
'd on the Parser
instance.
Lets say I have my custom phrases
<Alert>
- will match 'remind me 30 minutes before'
<Time>
- will match 'at 3pm'
<Contacts>
- will match 'with John`
I'd like to have phase like:
<choice multiple {/** or unordered? **/}>
<Alert/>
<Time/>
<Contacts/>
<freetext id="task"/>
</choice>
So that would match
remind me 30 minutes before with John at 3pm meeting about company
or in different order and not all the parts
meeting about company at 3pm with John
Is this possible with built-in phrases?
Right now <choice>
with limit greater than 1 allows picking more than one item, but they all are in different results.
Currently, each grammar is a javascript object with phrases
(strictly JSON), dependencies
(usually require
calls), and scope
(functions).
It was designed this way so that phrases
could be strictly JSON, so as to be easier to edit for non-technical translators. However, I have come to the conclusion that it only complicates things. For simple phrases, it doesn't make life any easier. For complex phrases (ones using validator
, suggester
, and list
for example), it dramatically complicates things.
I am proposing (and implementing) a change like so:
Rather than grammars being dumb objects, they will be instances of a class - in particular, lacona.Phrase. You make them by passing an object to lacona.createPhrase. You pass a single object, which must contain a name
and either a describe
(=> lacona.Phrase
) or schemas
([{langs: [lang], describe: => lacona.Phrase
}]}
var grammar = {
phrases: [{
name: 'test',
schemas: [{
langs: ['en', 'default'],
root: 'train'
}, {
langs: ['es'],
root: 'tren'
}]
}]
};
var Test = lacona.createPhrase({
name: 'Test',
schemas: [{
langs: ['en', 'default'],
describe: function () { return 'train'; }
}, {
langs: ['es'],
describe: function () { return 'tren'; }
}]
}
var grammar = {
phrases: [{
name: 'test',
root: {type: 'dep'}
}],
dependencies: [{
phrases: [{
name: 'dep',
describe: function () { return'something'; }
}]
}]
};
var Dep = lacona.createPhrase({
name: 'Dep',
describe: function () {
return 'something';}
});
var phrase = lacona.createPhrase({
name: 'Test',
root: Dep()
});
var grammar = {
scope: {
fun: function (input, data, done) {
data({display: 'disp', value: 'val'});
done();
}
},
phrases: [{
name: 'test',
root: {type: 'value', compute: 'fun', id: 'test'}
}]
};
var test = lacona.createPhrase({
name: 'test',
fun: function fun(input, data, done) {
data({display: 'disp', value: 'val'});
done();
},
describe: function () {
return lacona.value({compute: this.fun, id: 'test'});
}
});
function fun(done) {
done();
})
function depFun(input, data, done) {
this.$call('fun', function noop(err) {});
done();
}
var grammar = {
scope: {fun: fun},
phrases: [{
name: 'test',
root: {type: 'depPhrase'}
}],
dependencies: [{
scope: {depFun: depFun},
phrases: [{
name: 'depPhrase',
root: {type: 'value', compute: 'depFun'}
}]
}]
};
var DepPhrase = lacona.createPhrase({
name: 'DepPhrase',
depFun: function (input, data, done) {
this.props.fun();
done();
},
describe: function () {
return lacona.value({compute: this.depFun});
}
});
var Test = lacona.createPhrase({
name: 'Test',
fun: function () {console.log('fun');}
describe: fnunction () {
return DepPhrase({fun: this.fun});
}
});
var grammar = {
phrases: [{
name: 'test',
root: {
type: 'choice',
children: [
'right',
'wrong'
]
}
}]
};
var test = lacona.createPhrase({
name: 'test',
root: lacona.choice(null, [
'right',
'wrong'
])
};
var grammar = {
phrases: [{
name: 'extended',
root: 'test'
}, {
name: 'extender',
inherits: ['extended'],
root: 'totally'
}, {
name: 'test',
root: {type: 'extended'}
}]
};
var Extended = lacona.createPhrase({
name: 'Extended',
describe: function () {return 'test'; }
});
var Extender = lacona.createPhrase({
name: 'Extender',
extends: 'Extended',
describe: function () {return 'totally'; }
});
var Test = lacona.createPhrase({
name: 'Test',
describe: function () {return Extended(); }
)};
Closed
What's the best way to unit test custom phrases?
Let's imagine I'm creating a reusable phrase like Distance
with it looking approximately like
Distance =
<sequence>
<Number />
<choice>
<literal text='m' />
<literal text='mi' />
<literal text='mile' />
</choice>
</sequence>
My initial thought would be to create a list of valid and invalid inputs and loop over them to create tests. For example (not exact code just some pseudo code)
var validInputs = [{input: '10 mi', output: {value: 10, unit: units.miles}]
validInputs.forEach({input,output} -> {
it(`parses ${input} correctly`, -> distance.parse(input).result.is.equal.to(output));
})
In this case since there are multiple possible matches (mi and mile) I would be need to either add all possible matches to my tests cases or filter all the outputs to make sure my input / output combo is the best match.
Adding all possible matches seems fragile since any time I add a new choice literal I'd need to update all my units tests.
Filtering all the outputs feels like I'm fighting against the system.
What's the best way to handle this? Maybe I'm missing something or approaching it the wrong way.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.