1 /***************************************************************************
2 *
3 * Copyright 2012 BMW Car IT GmbH
4 *
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ****************************************************************************/
19 #include "ExpressionInterpreter.h"
20 #include "Expression.h"
21 #include "ilm_control.h"
22 #include <string>
23 #include <sstream>
24 #include <algorithm> // transform
25 #include <ctype.h> // tolower
26
27 #include <iostream>
28
29 Expression* ExpressionInterpreter::mpRoot = NULL;
30
ExpressionInterpreter()31 ExpressionInterpreter::ExpressionInterpreter()
32 : mErrorText("No error.")
33 {
34 }
35
addExpression(callback funcPtr,string command)36 bool ExpressionInterpreter::addExpression(callback funcPtr, string command)
37 {
38 bool result = false;
39
40 string text;
41 stringstream ss;
42 ss << command;
43
44 if (!mpRoot)
45 {
46 mpRoot = new Expression("[root]", NULL);
47 }
48
49 Expression* currentWord = mpRoot;
50
51 while (!ss.eof())
52 {
53 ss >> text;
54 transform(text.begin(), text.end(), text.begin(), ::tolower);
55
56 Expression* nextWord = currentWord->getNextExpression(text);
57
58 if (!nextWord)
59 {
60 nextWord = new Expression(text, currentWord);
61 currentWord->addNextExpression(nextWord);
62 }
63
64 currentWord = nextWord;
65 }
66
67 currentWord->setFunc(funcPtr);
68
69 return result;
70 }
71
interpretCommand(string userInput)72 CommandResult ExpressionInterpreter::interpretCommand(string userInput)
73 {
74 CommandResult result = CommandSuccess;
75 string text;
76 stringstream ss;
77 ss << userInput;
78
79 ExpressionList currentState;
80 currentState.push_back(mpRoot);
81 ExpressionList nextState;
82
83 while (result == CommandSuccess && !ss.eof())
84 {
85 ss >> text;
86
87 ExpressionList::const_iterator iter = currentState.begin();
88 ExpressionList::const_iterator end = currentState.end();
89 for (; iter != end; ++iter)
90 {
91 Expression* expr = *iter;
92 ExpressionList exprNextList = expr->getNextExpressionClosure(text);
93 nextState.splice(nextState.end(), exprNextList);
94 }
95
96 if (nextState.size() > 0)
97 {
98 currentState = nextState;
99 nextState.clear();
100 }
101 else
102 {
103 mErrorText = "'" + text + "' not recognized.";
104 result = CommandInvalid;
105 }
106 }
107
108 //remove impossible expressions in the final state before checking for ambiguity
109 nextState.clear();
110 ExpressionList::const_iterator iter = currentState.begin();
111 ExpressionList::const_iterator end = currentState.end();
112 for (; iter != end; ++iter)
113 {
114 Expression* expr = *iter;
115 if (expr->isExecutable())
116 {
117 nextState.push_back(expr);
118 }
119 else
120 {
121 ExpressionList children = expr->getNextExpressions();
122
123 bool flag = false;
124
125 ExpressionList::const_iterator iter = children.begin();
126 ExpressionList::const_iterator end = children.end();
127 for (; iter != end; ++iter)
128 {
129 if ((*iter)->getName()[0] == '[')
130 {
131 flag = true;
132 }
133 }
134
135 if (flag || children.size() == 0)
136 {
137 nextState.push_back(expr);
138 }
139 }
140 }
141
142 currentState = nextState;
143
144 if (currentState.size() != 1)
145 {
146 mErrorText = "'" + text + "' ambiguous or incomplete.";
147 result = CommandInvalid;
148 }
149
150 //run command if executable and non-ambiguous
151 if (result == CommandSuccess)
152 {
153 Expression* expr = *(currentState.begin());
154
155 ExpressionList executables = expr->getClosureExecutables(false);
156 if (executables.size() == 1)
157 {
158 ilmErrorTypes initResult = ilm_init();
159 if (ILM_SUCCESS != initResult)
160 {
161 mErrorText = ILM_ERROR_STRING(initResult);
162 result = CommandExecutionFailed;
163 }
164 else
165 {
166 Expression* exec = executables.front();
167 exec->execute();
168 ilm_commitChanges();
169 ilm_destroy();
170 }
171 }
172 else if (executables.size() == 0)
173 {
174 mErrorText = "command is incomplete.";
175 result = CommandIncomplete;
176 }
177 else
178 {
179 mErrorText = "command is ambiguous.";
180 result = CommandIncomplete;
181 }
182 }
183
184 return result;
185 }
186
printExpressionTree()187 void ExpressionInterpreter::printExpressionTree()
188 {
189 mpRoot->printTree();
190 }
191
printExpressionList()192 void ExpressionInterpreter::printExpressionList()
193 {
194 mpRoot->printList();
195 }
196
getLastError()197 string ExpressionInterpreter::getLastError()
198 {
199 string tmp = mErrorText;
200 mErrorText = "no error.";
201 return tmp;
202 }
203