convo
Version:
Easily create conversations (for more natural bots)
107 lines (95 loc) • 2.36 kB
JavaScript
/**
* Module dependencies
*/
var string_to_regexp = require('string-to-regexp')
var debug = require('debug')('convo:parse')
var TokenStream = require('token-stream')
var Lexer = require('./lexer')
/**
* Export `parse`
*/
module.exports = Parser
/**
* Initialize `parse`
*/
function Parser (tokens) {
if (!(this instanceof Parser)) return new Parser(tokens)
this.tokens = new TokenStream(tokens)
return this.choices()
}
/**
* Conversation
*/
Parser.prototype.choices = function() {
var choices = []
var choice = {}
while (true) {
switch(this.tokens.peek().type) {
case 'string':
choice.incoming = this.tokens.advance().val
break
case 'regexp':
choice.incoming = string_to_regexp(this.tokens.advance().val)
break
case 'arrow':
this.tokens.advance()
choice.outgoing = this.outgoing()
break
case 'alias':
choice.alias = this.tokens.advance().val
break
case 'newline':
this.tokens.advance()
Object.keys(choice).length && choices.push(choice)
choice = {}
break
case 'indent':
this.tokens.advance()
choice.outgoing.choices = this.choices()
Object.keys(choice).length && choices.push(choice)
choice = {}
break
case 'outdent':
this.tokens.advance()
Object.keys(choice).length && choices.push(choice)
return choices
case 'eos':
Object.keys(choice).length && choices.push(choice)
return choices
default:
throw new Error('unrecognized token', this.token.advance().type)
}
}
}
/**
* outgoing
*/
Parser.prototype.outgoing = function() {
var outgoing = {}
while (true) {
switch (this.tokens.peek().type) {
case 'alias':
outgoing.id = this.tokens.advance().val
break
case 'string':
outgoing.response = this.tokens.advance().val
break
case 'arrow':
this.tokens.advance()
break
case 'uparrow':
this.tokens.advance()
outgoing.reset = true
return outgoing
case 'variable':
outgoing.goto = this.tokens.advance().val
break
case 'indent':
case 'newline':
return outgoing
case 'outdent':
case 'eos':
return outgoing
}
}
}