MCPcopy Create free account
hub / github.com/daisy/MathCAT / build_intent

Function build_intent

src/infer_intent.rs:203–271  ·  view source on GitHub ↗
(rules_with_context: &'r mut SpeechRulesWithContext<'c,'s,'m>,
                                         lex_state: &mut LexState<'b>,
                                         mathml: Element<'c>)

Source from the content-addressed store, hash-verified

201}
202
203fn build_intent<'b, 'r, 'c, 's:'c, 'm:'c>(rules_with_context: &'r mut SpeechRulesWithContext<'c,'s,'m>,
204 lex_state: &mut LexState<'b>,
205 mathml: Element<'c>) -> Result<Element<'m>> {
206 // intent := self-property-list | expression
207 // self-property-list := property+ S
208 // expression := S ( term property* | application ) S
209 // term := concept-or-literal | number | reference
210 // concept-or-literal := NCName
211 // number := '-'? \d+ ( '.' \d+ )?
212 // reference := '$' NCName
213 // application := expression '(' arguments? S ')'
214 //
215 // When we flatten intent we have this implementation looking for Tokens or '(' [for application]
216 // Essentially, the grammar we deal with here is:
217 // intent := property+ | (concept-or-literal | number | reference) property* '('?
218 // debug!(" start build_intent: state: {}", lex_state);
219 let doc = rules_with_context.get_document();
220 let mut intent;
221 match lex_state.token {
222 Token::Property(_) => {
223 // We only have a property -- we want to keep this tag/element
224 // There are two paths:
225 // 1. If there is a function call, then the children are dealt with there
226 // 2. If there is *no* function call, then the children are kept, which means we return to pattern matching
227 // Note: to avoid infinite loop, we need to remove the 'intent' so we don't end up back here; we put it back later
228 let properties = get_properties(lex_state)?; // advance state to see if funcall
229 if lex_state.is_terminal("(") {
230 intent = create_mathml_element(&doc, name(&mathml));
231 intent.set_attribute_value(INTENT_PROPERTY, &properties);
232 } else {
233 let saved_intent = mathml.attribute_value("intent").unwrap();
234 mathml.remove_attribute("intent");
235 mathml.set_attribute_value(INTENT_PROPERTY, &properties); // needs to be set before the pattern match
236 intent = rules_with_context.match_pattern::<Element<'m>>(mathml)?;
237 mathml.set_attribute_value("intent", saved_intent);
238 }
239 return Ok(intent); // if we start with properties, then there can only be properties
240 },
241 Token::ConceptOrLiteral(word) | Token::Number(word) => {
242 let leaf_name = if let Token::Number(_) = lex_state.token {"mn"} else {"mi"};
243 intent = create_mathml_element(&doc, leaf_name);
244 intent.set_text(word); // '-' and '_' get removed by the rules.
245 lex_state.get_next()?;
246 if let Token::Property(_) = lex_state.token {
247 let properties = get_properties(lex_state)?;
248 intent.set_attribute_value(INTENT_PROPERTY, &properties);
249 }
250 },
251 Token::ArgRef(word) => {
252 intent = match find_arg(rules_with_context, &word[1..], mathml, true, false)? {
253 Some(e) => {
254 lex_state.get_next()?;
255 e
256 },
257 None => bail!("intent arg '{}' not found", word),
258 };
259 if let Token::Property(_) = lex_state.token {
260 let properties = get_properties(lex_state)?;

Callers 3

build_argumentsFunction · 0.85
find_argFunction · 0.85

Calls 8

get_propertiesFunction · 0.85
create_mathml_elementFunction · 0.85
nameFunction · 0.85
find_argFunction · 0.85
build_functionFunction · 0.85
get_documentMethod · 0.80
is_terminalMethod · 0.80
get_nextMethod · 0.80

Tested by

no test coverage detected