1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | var natural = require('natural');
|
10 | var tokenizer = new natural.WordTokenizer();
|
11 | var _ = require('underscore');
|
12 | var Hoek = require('hoek');
|
13 | var debug = require('debug')('parser');
|
14 |
|
15 | var COMMANDS = {
|
16 | en: {
|
17 | GO: 'go'
|
18 | , GET: 'get'
|
19 | , RESET: 'reset'
|
20 | , LOOK: 'look'
|
21 | , EXITS: 'exits'
|
22 | }
|
23 | }
|
24 | var ALIASES = {
|
25 | en: {
|
26 | 'walk': COMMANDS.en.GO
|
27 | , 'move': COMMANDS.en.GO
|
28 | , 'head': COMMANDS.en.GO
|
29 | , 'grab': COMMANDS.en.GET
|
30 | , 'take': COMMANDS.en.GET
|
31 | , 'pick': COMMANDS.en.GET
|
32 | , 'see': COMMANDS.en.LOOK
|
33 | , 'peep': COMMANDS.en.LOOK
|
34 | }
|
35 | }
|
36 | var OPERATORS = {
|
37 | en: ['in', 'on', 'up', 'if']
|
38 | }
|
39 | var LINKERS = {
|
40 | en: ['and', 'or', 'then']
|
41 | }
|
42 | var FLUFF = {
|
43 | en: ['the']
|
44 | }
|
45 |
|
46 | var advtxt = {};
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | exports = module.exports = advtxt.Parser = function(command, lang) {
|
61 | var self = this;
|
62 |
|
63 |
|
64 | if (typeof lang === 'undefined' || !lang) {
|
65 | debug("Setting lang to 'en'.");
|
66 | lang = 'en';
|
67 | }
|
68 |
|
69 |
|
70 | if (typeof self.parse[lang] !== 'undefined')
|
71 | return self.parse[lang](command.command);
|
72 | else
|
73 | throw "advtxt.Parser: language " + lang + " does not have an appropriate parser defined.";
|
74 | }
|
75 |
|
76 | advtxt.Parser.prototype.parse = {};
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 | advtxt.Parser.prototype.parse["en"] = function(cmd) {
|
85 | var self = this;
|
86 |
|
87 | debug("Starting to parse English.");
|
88 |
|
89 | var tokenized = tokenizer.tokenize(cmd.toLowerCase());
|
90 | var original_verb = null;
|
91 | var verb = null;
|
92 | var object = null;
|
93 | var operator = null;
|
94 |
|
95 |
|
96 | tokenized = _.difference(tokenized, FLUFF);
|
97 |
|
98 |
|
99 | if (_.intersection(tokenized, LINKERS).length > 0) {
|
100 | debug("Got a linker word.");
|
101 | self.fail = true;
|
102 | return self;
|
103 | }
|
104 |
|
105 |
|
106 | if (tokenized.length > 2 && _.contains(OPERATORS["en"], tokenized[1])) {
|
107 | debug("Command contains operator in position 1");
|
108 | verb = tokenized[0];
|
109 | operator = tokenized[1];
|
110 | object = tokenized.slice(2).join("_");
|
111 | }
|
112 |
|
113 | else {
|
114 | verb = tokenized[0];
|
115 | object = tokenized.slice(1).join("_");
|
116 | }
|
117 |
|
118 |
|
119 | if (typeof ALIASES.en[verb] !== 'undefined' && ALIASES.en[verb]) {
|
120 | debug("Parser saw an alias.");
|
121 | original_verb = Hoek.clone(verb);
|
122 | verb = ALIASES.en[verb];
|
123 | debug(verb);
|
124 | }
|
125 | else {
|
126 | debug("Setting verb");
|
127 | verb = COMMANDS.en[verb.toUpperCase()];
|
128 | if (typeof verb === 'undefined' || !verb) {
|
129 | verb = tokenized[0];
|
130 | }
|
131 | debug(verb);
|
132 | }
|
133 |
|
134 | cmd = {
|
135 | original: cmd,
|
136 | original_verb: original_verb,
|
137 | lang: self.lang,
|
138 | verb: verb,
|
139 | object: object
|
140 | }
|
141 |
|
142 | self.fail = false;
|
143 | self.command = cmd;
|
144 | self.commands = COMMANDS.en;
|
145 | debug(JSON.stringify(cmd));
|
146 |
|
147 | return self;
|
148 | };
|