FAUST compiler  0.9.9.6b8
Functions
patternmatcher.hh File Reference
#include <vector>
#include "tlib.hh"
Include dependency graph for patternmatcher.hh:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

Automatonmake_pattern_matcher (Tree R)
 
int apply_pattern_matcher (Automaton *A, int s, Tree X, Tree &C, vector< Tree > &E)
 

Function Documentation

int apply_pattern_matcher ( Automaton A,
int  s,
Tree  X,
Tree C,
vector< Tree > &  E 
)

Definition at line 660 of file patternmatcher.cpp.

References apply_pattern_matcher_internal(), boxError(), closure(), Automaton::final(), isBoxError(), Automaton::n_rules(), nil, pushValueDef(), Automaton::rhs, Automaton::rules(), searchIdDef(), subst(), and subtree().

Referenced by applyList(), and make_pattern_matcher().

665 {
666  int n = A->n_rules();
667  vector<Subst> subst(n, Subst());
668  /* perform matching, record variable substitutions */
669 #ifdef DEBUG
670  cerr << "automaton " << A << ", state " << s << ", start match on arg: " << *X << endl;
671 #endif
673  C = nil;
674  if (s < 0)
675  /* failed match */
676  return s;
677  /* process variable substitutions */
678  list<Rule>::const_iterator r;
679  for (r = A->rules(s).begin(); r != A->rules(s).end(); r++) {
680  // all rules still active in state s
681  if (!isBoxError(E[r->r])) { // and still viable
682  Subst::const_iterator assoc;
683  for (assoc = subst[r->r].begin(); assoc != subst[r->r].end(); assoc++) {
684  Tree Z, Z1 = subtree(X, 0, assoc->p);
685  if (searchIdDef(assoc->id, Z, E[r->r])) {
686  if (Z != Z1) {
687  /* failed nonlinearity, add to the set of nonviable rules */
688 #ifdef DEBUG
689  cerr << "state " << s << ", rule #" << r->r << ": " <<
690  *assoc->id << " := " << *Z1 << " *** failed *** old value: " <<
691  *Z << endl;
692 #endif
693  E[r->r] = boxError();
694  }
695  } else {
696  /* bind a variable for the current rule */
697 #ifdef DEBUG
698  cerr << "state " << s << ", rule #" << r->r << ": " <<
699  *assoc->id << " := " << *Z1 << endl;
700 #endif
701  E[r->r] = pushValueDef(assoc->id, Z1, E[r->r]);
702  }
703  }
704  }
705  }
706  if (A->final(s)) {
707  /* if in a final state then return the right-hand side together with the
708  corresponding variable environment */
709  for (r = A->rules(s).begin(); r != A->rules(s).end(); r++) // all rules matched in state s
710  if (!isBoxError(E[r->r])) { // and still viable
711  /* return the rhs of the matched rule */
712  C = closure(A->rhs[r->r], nil, nil, E[r->r]);
713 #ifdef DEBUG
714  cerr << "state " << s << ", complete match yields rhs #" << r->r <<
715  ": " << *A->rhs[r->r] << endl;
716 #endif
717  return s;
718  }
719  /* if none of the rules were matched then declare a failed match */
720 #ifdef DEBUG
721  cerr << "state " << s << ", *** match failed ***" << endl;
722 #endif
723  return -1;
724  }
725 #ifdef DEBUG
726  cerr << "state " << s << ", successful incomplete match" << endl;
727 #endif
728  return s;
729 }
Tree pushValueDef(Tree id, Tree def, Tree lenv)
Push a new layer and add a single definition.
Definition: environment.cpp:94
static Tree subtree(Tree X, int i, const Path &p)
bool searchIdDef(Tree id, Tree &def, Tree lenv)
Search the environment (until first barrier) for the definition of a symbol ID and return it...
A CTree = (Node x [CTree]) is a Node associated with a list of subtrees called branches.
Definition: tree.hh:109
bool final(int s)
list< Assoc > Subst
vector< Tree > rhs
string subst(const string &model, const vector< string > &args)
Text substitution.
Definition: Text.cpp:47
static int apply_pattern_matcher_internal(Automaton *A, int s, Tree X, vector< Subst > &subst)
Tree boxError()
Definition: boxes.cpp:244
Tree closure(Tree abstr, Tree genv, Tree vis, Tree lenv)
Definition: boxes.cpp:234
Tree nil
Definition: list.cpp:116
const list< Rule > & rules(int s)
bool isBoxError(Tree t)
Definition: boxes.cpp:249

Here is the call graph for this function:

Here is the caller graph for this function:

Automaton* make_pattern_matcher ( Tree  R)

Definition at line 479 of file patternmatcher.cpp.

References apply_pattern_matcher(), Automaton::build(), Automaton::final(), isBoxError(), isCons(), len(), make_state(), merge_state(), nil, reverse(), Automaton::rhs, State::rules, and Automaton::rules().

Referenced by evalCase().

491 {
492  Automaton *A = new Automaton;
493  int n = len(R), r = n;
494  State *start = new State;
495  Tree rule, rest;
496  vector<Tree> rules(n, (Tree)NULL);
497  vector< vector<Tree> > testpats(n);
498  while (isCons(R, rule, rest)) {
499  rules[--r] = rule;
500  R = rest;
501  }
502  for (r = 0; r < n; r++) {
503  Tree lhs, rhs;
504  if (isCons(rules[r], lhs, rhs)) {
505  Tree pat, rest;
506  int m = len(lhs), i = m;
507  vector<Tree> pats(len(lhs), (Tree)NULL);
508  State *state0 = new State, *state = state0;
509  A->rhs.push_back(rhs);
510  while (isCons(lhs, pat, rest)) {
511  pats[--i] = pat;
512  lhs = rest;
513  }
514  testpats[r] = pats;
515  for (i = 0; i < m; i++) {
516  Path p;
517  state = make_state(state, r, pats[i], p);
518  }
519  Rule rule(r, NULL);
520  state->rules.push_back(rule);
521  merge_state(start, state0);
522  delete state0;
523  }
524  }
525  A->build(start);
526  /* Check for shadowed rules. Note that because of potential nonlinearities
527  it is *not* enough to just check the rule lists of final states and
528  determine whether they have multiple matched rules. */
529  for (r = 0; r < n; r++) {
530  int s = 0, m = (int)testpats[r].size();
531  Tree C;
532  vector<Tree> E(n, nil);
533  /* try to match the lhs of rule #r */
534  for (int i = 0; i < m; i++) {
535  s = apply_pattern_matcher(A, s, testpats[r][i], C, E);
536  if (s < 0) break;
537  }
538  if (A->final(s)) {
539  list<Rule>::const_iterator ru;
540  for (ru = A->rules(s).begin(); ru != A->rules(s).end(); ru++)
541  if (!isBoxError(E[ru->r]))
542  if (ru->r < r) {
543  /* Lhs of rule #r matched a higher-priority rule, so rule #r may
544  be shadowed. */
545  Tree lhs1, rhs1, lhs2, rhs2;
546  if (isCons(rules[ru->r], lhs1, rhs1) && isCons(rules[r], lhs2, rhs2)) {
547  cerr << "WARNING : shadowed pattern-matching rule: "
548  << boxpp(reverse(lhs2)) << " => " << boxpp(rhs2) << ";"
549  << " previous rule was: "
550  << boxpp(reverse(lhs1)) << " => " << boxpp(rhs1) << ";"
551  << endl;
552  } else {
553  cerr << "INTERNAL ERROR : " << __FILE__ << ":" << __LINE__ << endl;
554  exit(1);
555  }
556  } else if (ru->r >= r)
557  break;
558  }
559  }
560 #ifdef DEBUG
561  cerr << "automaton " << A << endl << *A << "end automaton" << endl;
562 #endif
563  return A;
564 }
Tree reverse(Tree l)
Definition: list.cpp:240
static State * make_state(State *state, int r, Tree x, Path &p)
A CTree = (Node x [CTree]) is a Node associated with a list of subtrees called branches.
Definition: tree.hh:109
list< Rule > rules
bool final(int s)
vector< Tree > rhs
static bool isCons(Tree x, Tree &h, Tree &t)
vector< int > Path
void build(State *st)
Definition: ppbox.hh:58
Tree nil
Definition: list.cpp:116
const list< Rule > & rules(int s)
static void merge_state(State *state1, State *state2)
bool isBoxError(Tree t)
Definition: boxes.cpp:249
int apply_pattern_matcher(Automaton *A, int s, Tree X, Tree &C, vector< Tree > &E)
int len(Tree l)
Definition: list.cpp:198

Here is the call graph for this function:

Here is the caller graph for this function: