Пример #1
0
static int choice(int p1,int p2) {
  if(P_IS(p1,P_NOT_ALLOWED)) return p2;
  if(P_IS(p2,P_NOT_ALLOWED)) return p1;
  if(P_IS(p2,P_CHOICE)) {
    int p21,p22; Choice(p2,p21,p22);
    p1=choice(p1,p21); return choice(p1,p22);
  }
  if(samechoice(p1,p2)) return p1;
  if(nullable(p1) && (P_IS(p2,P_EMPTY))) return p1;
  if(nullable(p2) && (P_IS(p1,P_EMPTY))) return p2;
  return newChoice(p1,p2);
}
Пример #2
0
void TypeConstraint::verifyFail(const Func* func, int paramNum,
                                const TypedValue* tv) const {
  Transl::VMRegAnchor _;
  std::ostringstream fname;
  fname << func->fullName()->data() << "()";
  const StringData* tn = typeName();
  if (isSelf()) {
    selfToTypeName(func, &tn);
  } else if (isParent()) {
    parentToTypeName(func, &tn);
  }

  auto const givenType = describe_actual_type(tv);

  if (isExtended()) {
    // Extended type hints raise warnings instead of recoverable
    // errors for now, to ease migration (we used to not check these
    // at all at runtime).
    assert(nullable() &&
           "only nullable extended type hints are currently supported");
    raise_warning(
      "Argument %d to %s must be of type ?%s, %s given",
      paramNum + 1, fname.str().c_str(), tn->data(), givenType);
  } else {
    raise_recoverable_error(
      "Argument %d passed to %s must be an instance of %s, %s given",
      paramNum + 1, fname.str().c_str(), tn->data(), givenType);
  }
}
Пример #3
0
/*
** p^n
*/
static int lp_star (lua_State *L) {
  int size1;
  int n = (int)luaL_checkinteger(L, 2);
  TTree *tree1 = getpatt(L, 1, &size1);
  if (n >= 0) {  /* seq tree1 (seq tree1 ... (seq tree1 (rep tree1))) */
    TTree *tree = newtree(L, (n + 1) * (size1 + 1));
    if (nullable(tree1))
      luaL_error(L, "loop body may accept empty string");
    while (n--)  /* repeat 'n' times */
      tree = seqaux(tree, tree1, size1);
    tree->tag = TRep;
    memcpy(sib1(tree), tree1, size1 * sizeof(TTree));
  }
  else {  /* choice (seq tree1 ... choice tree1 true ...) true */
    TTree *tree;
    n = -n;
    /* size = (choice + seq + tree1 + true) * n, but the last has no seq */
    tree = newtree(L, n * (size1 + 3) - 1);
    for (; n > 1; n--) {  /* repeat (n - 1) times */
      tree->tag = TChoice; tree->u.ps = n * (size1 + 3) - 2;
      sib2(tree)->tag = TTrue;
      tree = sib1(tree);
      tree = seqaux(tree, tree1, size1);
    }
    tree->tag = TChoice; tree->u.ps = size1 + 1;
    sib2(tree)->tag = TTrue;
    memcpy(sib1(tree), tree1, size1 * sizeof(TTree));
  }
  copyktable(L, 1);
  return 1;
}
Пример #4
0
int rx_cmatch(char *rx,char *s,int n) {
  int p=compile(rx);
  if(!errors) {
    char *end=s+n;
    int u;
    SKIP_SPACE: for(;;) {
      if(s==end) return nullable(p);
      s+=u_get(&u,s);
      if(!xmlc_white_space(u)) break;
    }
    for(;;) {
      if(p==notAllowed) return 0;
      if(xmlc_white_space(u)) { u=' ';
	p=drv(p,u);
	if(p==notAllowed) {
	  for(;;) {
	    if(s==end) return 1;
	    s+=u_get(&u,s);
	    if(!xmlc_white_space(u)) return 0;
	  }
	} else goto SKIP_SPACE;
      }
      p=drv(p,u);
      if(s==end) goto SKIP_SPACE;
      s+=u_get(&u,s);
    }
  } else return 0;
}
Пример #5
0
bool
TypeConstraint::checkPrimitive(DataType dt) const {
  assert(m_type.m_dt != KindOfObject);
  assert(dt != KindOfRef);
  if (nullable() && IS_NULL_TYPE(dt)) return true;
  return equivDataTypes(m_type.m_dt, dt);
}
Пример #6
0
/* Parser parsing 
 * create first follow nullable and table then parsing token
 * finally output parsing tree
 * */
void Parser:: startParsing(vector<Token*> tokens){
	
	vector<Nonterminal*>::iterator itr;
	vector<list<string> > starting_Production;
	list<string> body;

	//find nullable
	for( itr = non_terminals.begin(); itr!= non_terminals.end(); ++itr ){
		(*itr) -> nullable = nullable( (*itr) -> term );
	}

	// add a production: S -> Program $
	Nonterminal* startState = new Nonterminal("S");
	startState -> nullable = non_terminals[0] -> nullable;
	non_terminals.push_back( startState );
	body.push_back( non_terminals[0]-> term );
	body.push_back( "$" );
	starting_Production.push_back(body);
	grammar.insert( make_pair("S", starting_Production) );

	//find first
	for( itr = non_terminals.begin(); itr!= non_terminals.end(); ++itr ){
		if ( (*itr) -> first.empty() ){
			(*itr) -> first = first( (*itr) -> term );		
		}
	}

	set<string>:: iterator itr2;
	
	//find follow
	follow();

	//output set.txt include nullable first and follow
	outputSet();
	
	// build Parsing table by if nullalbe is exist
	for(itr = non_terminals.begin(); itr != non_terminals.end(); ++itr){
		if( (*itr)->nullable ){
			for(set<string>::iterator follow_itr = (*itr) -> follow.begin(); \
							follow_itr != (*itr) -> follow.end(); ++follow_itr ){
				if( (*itr)->first.find( (*follow_itr) ) == (*itr)->first.end() ){
					map<string, map<string, int> >::iterator non_terminal_find_itr = parsingTable.find( (*itr)-> term );
					if ( non_terminal_find_itr == parsingTable.end() ){
						//parsingTable.insert( make_pair((*itr),   ) );	
					}
					else{
						non_terminal_find_itr -> second.insert( make_pair(*follow_itr, (*itr)-> production_nullable ) );
					}
				}
			}
		}
	}
	
	// output table
	outputParingTable();
	
	// create Parsing Tree and ouput it
	createParsingTree(tokens);
}
Пример #7
0
static int drv(int p,int c) {
  int p1,p2,cf,cl,cn,ret,m;
  assert(!P_IS(p,P_ERROR));
  m=new_memo(p,c);
  if(m!=-1) return M_RET(m);
  switch(P_TYP(p)) {
  case P_NOT_ALLOWED: case P_EMPTY: ret=notAllowed; break;
  case P_CHOICE: Choice(p,p1,p2); ret=choice(drv(p1,c),drv(p2,c)); break;
  case P_GROUP: Group(p,p1,p2); {int p11=group(drv(p1,c),p2); ret=nullable(p1)?choice(p11,drv(p2,c)):p11;} break;
  case P_ONE_OR_MORE: OneOrMore(p,p1); ret=group(drv(p1,c),choice(empty,p)); break;
  case P_EXCEPT: Except(p,p1,p2); ret=nullable(drv(p1,c))&&!nullable(drv(p2,c))?empty:notAllowed; break;
  case P_RANGE: Range(p,cf,cl); ret=cf<=c&&c<=cl?empty:notAllowed; break;
  case P_CLASS: Class(p,cn); ret=in_class(c,cn)?empty:notAllowed; break;
  case P_ANY: ret=empty; break;
  case P_CHAR: Char(p,cf); ret=c==cf?empty:notAllowed; break;
  default: ret=0; assert(0);
  }
  new_memo(p,c); M_SET(ret);
  accept_m();
  return ret;
}
Пример #8
0
Файл: dreg.c Проект: scythe/dreg
int nullable(regex *r) {
	int ind, k = 1;

	switch(r->type) {
		case COMPL:
			return !nullable(r->operands[0]);
		case KLEENE:
			return 1;
		case OR:
			k = 0;
		case AND:
		case CONCAT:
			for(ind = 0; ind < r->oplen; ++ind)
				if(nullable(r->operands[ind]) - k)
					return !k;
			return k;
		case SET:
			return 0;
	}
	exit(1);
}
Пример #9
0
int rx_match(char *rx,char *s,int n) {
  int p=compile(rx);
  if(!errors) {
    char *end=s+n;
    int u;
    for(;;) {
      if(p==notAllowed) return 0;
      if(s==end) return nullable(p);
      s+=u_get(&u,s);
      p=drv(p,u);
    }
  } else return 0;
}
Пример #10
0
TEST_F(TestCFG, BNF) {
    auto test = CFG::create(BNF());
    ASSERT_NO_THROW(test << "<S> ::= 'a'<A>'b' | ''");
    ASSERT_NO_THROW(test << "<A> ::= 'a'<A> | 'b'<A> | ''");
    EXPECT_EQ(set({"a", "b"}), test.getTerminals());
    EXPECT_EQ(set({"<S>", "<A>"}), test.getNonTerminals());

    test.clear();
    test << "<S> ::= <S>'s' | <B><C><D>";
    test << "<A> ::= <S><A>'a' | ''";
    test << "<B> ::= <C>'c'";
    test << "<C> ::= <B>'b' | <S>'s' | <A>";
    test << "<D> ::= <D>'d' | <D><B> | ''";
    ASSERT_EQ(set({"c"}), test.first("<S>"));
    ASSERT_EQ(set({"c"}), test.first("<A>"));
    ASSERT_EQ(set({"c"}), test.first("<B>"));
    ASSERT_EQ(set({"c"}), test.first("<C>"));
    ASSERT_EQ(set({"c", "d"}), test.first("<D>"));
    ASSERT_FALSE(test.nullable("<S>"));
    ASSERT_TRUE(test.nullable("<A>"));
    ASSERT_FALSE(test.nullable("<B>"));
    ASSERT_TRUE(test.nullable("<C>"));
    ASSERT_TRUE(test.nullable("<D>"));
}
Пример #11
0
TEST_F(TestCFG, DidacticNotation) {
    auto test = CFG::create(DidacticNotation());
    ASSERT_NO_THROW(test << "S -> a A b | ");
    ASSERT_NO_THROW(test << "A -> a A | b A | ");
    EXPECT_EQ(set({"a", "b"}), test.getTerminals());
    EXPECT_EQ(set({"S", "A"}), test.getNonTerminals());

    test.clear();
    test << "S -> S s | B C D";
    test << "A -> S A a | ";
    test << "B -> C c";
    test << "C -> B b | S s | A";
    test << "D -> D d | D B | ";
    ASSERT_EQ(set({"c"}), test.first("S"));
    ASSERT_EQ(set({"c"}), test.first("A"));
    ASSERT_EQ(set({"c"}), test.first("B"));
    ASSERT_EQ(set({"c"}), test.first("C"));
    ASSERT_EQ(set({"c", "d"}), test.first("D"));
    ASSERT_FALSE(test.nullable("S"));
    ASSERT_TRUE(test.nullable("A"));
    ASSERT_FALSE(test.nullable("B"));
    ASSERT_TRUE(test.nullable("C"));
    ASSERT_TRUE(test.nullable("D"));
}
Пример #12
0
/**********************************************************************
 *
 *	set_pos
 *
 * Sets nullable, firstpos and lastpos in whole tree.
 */
static bool set_pos(void)
{
	REG1 int	i;
	REG2 node_t*	tnode = rbuf.tree;
	
	for (i = 0; i <= rbuf.root; i++, tnode++) {
		nullable(tnode);
		if ((tnode->firstpos = calloc(rbuf.setsize, 1)) == NULL)
			return FALSE;
		firstpos(i, tnode);
		if ((tnode->lastpos = calloc(rbuf.setsize, 1)) == NULL)
			return FALSE;
		lastpos(i, tnode);
	}
	return TRUE;
}
Пример #13
0
/*
** Check whether a tree has potential infinite loops
*/
static int checkloops (TTree *tree) {
 tailcall:
  if (tree->tag == TRep && nullable(sib1(tree)))
    return 1;
  else if (tree->tag == TGrammar)
    return 0;  /* sub-grammars already checked */
  else {
    switch (numsiblings[tree->tag]) {
      case 1:  /* return checkloops(sib1(tree)); */
        tree = sib1(tree); goto tailcall;
      case 2:
        if (checkloops(sib1(tree))) return 1;
        /* else return checkloops(sib2(tree)); */
        tree = sib2(tree); goto tailcall;
      default: assert(numsiblings[tree->tag] == 0); return 0;
    }
  }
}
Пример #14
0
/*
** Check whether a rule can be left recursive; raise an error in that
** case; otherwise return 1 iff pattern is nullable.
** The return value is used to check sequences, where the second pattern
** is only relevant if the first is nullable.
** Parameter 'nb' works as an accumulator, to allow tail calls in
** choices. ('nb' true makes function returns true.)
** Assume ktable at the top of the stack.
*/
static int verifyrule (lua_State *L, TTree *tree, int *passed, int npassed,
                       int nb) {
 tailcall:
  switch (tree->tag) {
    case TChar: case TSet: case TAny:
    case TFalse:
      return nb;  /* cannot pass from here */
    case TTrue:
    case TBehind:  /* look-behind cannot have calls */
      return 1;
    case TNot: case TAnd: case TRep:
      /* return verifyrule(L, sib1(tree), passed, npassed, 1); */
      tree = sib1(tree); nb = 1; goto tailcall;
    case TCapture: case TRunTime:
      /* return verifyrule(L, sib1(tree), passed, npassed, nb); */
      tree = sib1(tree); goto tailcall;
    case TCall:
      /* return verifyrule(L, sib2(tree), passed, npassed, nb); */
      tree = sib2(tree); goto tailcall;
    case TSeq:  /* only check 2nd child if first is nb */
      if (!verifyrule(L, sib1(tree), passed, npassed, 0))
        return nb;
      /* else return verifyrule(L, sib2(tree), passed, npassed, nb); */
      tree = sib2(tree); goto tailcall;
    case TChoice:  /* must check both children */
      nb = verifyrule(L, sib1(tree), passed, npassed, nb);
      /* return verifyrule(L, sib2(tree), passed, npassed, nb); */
      tree = sib2(tree); goto tailcall;
    case TRule:
      if (npassed >= MAXRULES)
        return verifyerror(L, passed, npassed);
      else {
        passed[npassed++] = tree->key;
        /* return verifyrule(L, sib1(tree), passed, npassed); */
        tree = sib1(tree); goto tailcall;
      }
    case TGrammar:
      return nullable(tree);  /* sub-grammar cannot be left recursive */
    default: assert(0); return 0;
  }
}
Пример #15
0
TupleSchema* TableCatalogDelegate::createTupleSchema(catalog::Table const& catalogTable,
                                                     bool isXDCR) {
    // Columns:
    // Column is stored as map<std::string, Column*> in Catalog. We have to
    // sort it by Column index to preserve column order.
    auto numColumns = catalogTable.columns().size();
    bool needsDRTimestamp = isXDCR && catalogTable.isDRed();
    TupleSchemaBuilder schemaBuilder(numColumns,
                                     needsDRTimestamp ? 1 : 0); // number of hidden columns

    std::map<std::string, catalog::Column*>::const_iterator colIterator;
    for (colIterator = catalogTable.columns().begin();
         colIterator != catalogTable.columns().end(); colIterator++) {

        auto catalogColumn = colIterator->second;
        schemaBuilder.setColumnAtIndex(catalogColumn->index(),
                                       static_cast<ValueType>(catalogColumn->type()),
                                       static_cast<int32_t>(catalogColumn->size()),
                                       catalogColumn->nullable(),
                                       catalogColumn->inbytes());
    }

    if (needsDRTimestamp) {
        // Create a hidden timestamp column for a DRed table in an
        // active-active context.
        //
        // Column will be marked as not nullable in TupleSchema,
        // because we never expect a null value here, but this is not
        // actually enforced at runtime.
        schemaBuilder.setHiddenColumnAtIndex(0,
                                             VALUE_TYPE_BIGINT,
                                             8,      // field size in bytes
                                             false); // nulls not allowed
    }

    return schemaBuilder.build();
}
Пример #16
0
/* build nullable
 * */
bool Parser:: nullable(string term){

	map<string, vector<list<string> > >::iterator itr = grammar.find(term);
	int production_null_index = 0; // record which production produce nullable	
	bool isNullable = true;

	// iterator each prduction
	for( vector<list<string> >::iterator itr2 = (itr->second).begin(); itr2 != (itr-> second).end(); ++itr2 ){

		// iterator body term
		for( list<string>::iterator itr3 = (*itr2).begin(); itr3 != (*itr2).end(); ++itr3 ){
		
			// is nullable
			if( (*itr3).compare("epsilon") == 0 ){
				break;
			}
			// is a terminal or is a nullable non_terminal
			else if( isTerminal( (*itr3) )  || !nullable(*itr3) ){
				isNullable = false;
				break;
			}
		}

		if( isNullable ){
			// readcord which production produce nullable
			map<string, Nonterminal*>::iterator non_terminal = non_terminals_map.find(term);
			non_terminal->second->production_nullable = production_null_index;
			return true;
		}
		
		// reset and go to next production
		isNullable = true;
		production_null_index += 1;
	}
	return false;
}
Пример #17
0
static int newGroup(int p1,int p2) {P_newbinop(P_GROUP,p1,p2); setNullable(nullable(p1)&&nullable(p2)); return accept_p();}
Пример #18
0
static int newChoice(int p1,int p2) {P_newbinop(P_CHOICE,p1,p2); setNullable(nullable(p1)||nullable(p2)); return accept_p();}
Пример #19
0
static int newOneOrMore(int p1) {P_newunop(P_ONE_OR_MORE,p1); setNullable(nullable(p1)); return accept_p();}
Пример #20
0
void TypeConstraint::init() {
  if (UNLIKELY(s_typeNamesToTypes.empty())) {
    const struct Pair {
      const StringData* name;
      Type type;
    } pairs[] = {
      { StringData::GetStaticString("bool"),     { KindOfBoolean,
                                                   MetaType::Precise }},
      { StringData::GetStaticString("boolean"),  { KindOfBoolean,
                                                   MetaType::Precise }},

      { StringData::GetStaticString("int"),      { KindOfInt64,
                                                   MetaType::Precise }},
      { StringData::GetStaticString("integer"),  { KindOfInt64,
                                                   MetaType::Precise }},

      { StringData::GetStaticString("real"),     { KindOfDouble,
                                                   MetaType::Precise }},
      { StringData::GetStaticString("double"),   { KindOfDouble,
                                                   MetaType::Precise }},
      { StringData::GetStaticString("float"),    { KindOfDouble,
                                                   MetaType::Precise }},

      { StringData::GetStaticString("string"),   { KindOfString,
                                                   MetaType::Precise }},

      { StringData::GetStaticString("array"),    { KindOfArray,
                                                   MetaType::Precise }},

      { StringData::GetStaticString("resource"), { KindOfResource,
                                                   MetaType::Precise }},

      { StringData::GetStaticString("self"),     { KindOfObject,
                                                   MetaType::Self }},
      { StringData::GetStaticString("parent"),   { KindOfObject,
                                                   MetaType::Parent }},
      { StringData::GetStaticString("callable"), { KindOfObject,
                                                   MetaType::Callable }},
    };
    for (unsigned i = 0; i < sizeof(pairs) / sizeof(Pair); ++i) {
      s_typeNamesToTypes[pairs[i].name] = pairs[i].type;
    }
  }

  if (m_typeName && isExtended()) {
    assert(nullable() &&
           "Only nullable extended type hints are implemented");
  }

  if (blacklistedName(m_typeName)) {
    m_typeName = nullptr;
  }
  if (m_typeName == nullptr) {
    m_type.m_dt = KindOfInvalid;
    m_type.m_metatype = MetaType::Precise;
    return;
  }

  Type dtype;
  TRACE(5, "TypeConstraint: this %p type %s, nullable %d\n",
        this, m_typeName->data(), nullable());
  if (!mapGet(s_typeNamesToTypes, m_typeName, &dtype) ||
      !(hhType() || dtype.m_dt == KindOfArray || dtype.isParent() ||
        dtype.isSelf())) {
    TRACE(5, "TypeConstraint: this %p no such type %s, treating as object\n",
          this, m_typeName->data());
    m_type = { KindOfObject, MetaType::Precise };
    m_namedEntity = Unit::GetNamedEntity(m_typeName);
    TRACE(5, "TypeConstraint: NamedEntity: %p\n", m_namedEntity);
    return;
  }
  m_type = dtype;
  assert(m_type.m_dt != KindOfStaticString);
  assert(IMPLIES(isParent(), m_type.m_dt == KindOfObject));
  assert(IMPLIES(isSelf(), m_type.m_dt == KindOfObject));
  assert(IMPLIES(isCallable(), m_type.m_dt == KindOfObject));
}
Пример #21
0
bool
TypeConstraint::check(const TypedValue* tv, const Func* func) const {
  assert(hasConstraint());

  // This is part of the interpreter runtime; perf matters.
  if (tv->m_type == KindOfRef) {
    tv = tv->m_data.pref->tv();
  }
  if (nullable() && IS_NULL_TYPE(tv->m_type)) return true;

  if (tv->m_type == KindOfObject) {
    if (!isObjectOrTypedef()) return false;
    // Perfect match seems common enough to be worth skipping the hash
    // table lookup.
    if (m_typeName->isame(tv->m_data.pobj->getVMClass()->name())) {
      if (shouldProfile()) Class::profileInstanceOf(m_typeName);
      return true;
    }
    const Class *c = nullptr;
    const bool selfOrParentOrCallable = isSelf() || isParent() || isCallable();
    if (selfOrParentOrCallable) {
      if (isSelf()) {
        selfToClass(func, &c);
      } else if (isParent()) {
        parentToClass(func, &c);
      } else {
        assert(isCallable());
        return f_is_callable(tvAsCVarRef(tv));
      }
    } else {
      // We can't save the Class* since it moves around from request
      // to request.
      assert(m_namedEntity);
      c = Unit::lookupClass(m_namedEntity);
    }
    if (shouldProfile() && c) {
      Class::profileInstanceOf(c->preClass()->name());
    }
    if (c && tv->m_data.pobj->instanceof(c)) {
      return true;
    }
    return !selfOrParentOrCallable && checkTypedefObj(tv);
  }

  if (isObjectOrTypedef()) {
    switch (tv->m_type) {
      case KindOfArray:
        if (interface_supports_array(m_typeName)) {
          return true;
        }
        break;
      case KindOfString:
      case KindOfStaticString:
        if (interface_supports_string(m_typeName)) {
          return true;
        }
        break;
      case KindOfInt64:
        if (interface_supports_int(m_typeName)) {
          return true;
        }
        break;
      case KindOfDouble:
        if (interface_supports_double(m_typeName)) {
          return true;
        }
        break;
      default:
        break;
    }

    if (isCallable()) {
      return f_is_callable(tvAsCVarRef(tv));
    }
    return isPrecise() && checkTypedefNonObj(tv);
  }

  return equivDataTypes(m_type.m_dt, tv->m_type);
}