⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lexert.cc

📁 COPE the first practical network coding scheme which is developped on click
💻 CC
📖 第 1 页 / 共 2 页
字号:
	}    }    ElementT *e = _router->get_element(name, type, conf, lm ? lm : landmark());    _lexinfo->notify_element_declaration(e, location.pos1(), location.pos2(), (decl_pos2 < 0 ? location.pos2() : decl_pos2));    return e->eindex();}intLexerT::make_anon_element(const Lexeme &what, int decl_pos2,			  ElementClassT *type, const String &conf,			  const String &lm){    return make_element(anon_element_name(type->name()), what, decl_pos2, type, conf, lm);}voidLexerT::connect(int element1, int port1, int port2, int element2){    if (port1 < 0)	port1 = 0;    if (port2 < 0)	port2 = 0;    _router->add_connection	(PortT(_router->element(element1), port1),	 PortT(_router->element(element2), port2), landmark());}// PARSINGboolLexerT::yport(int &port, int &pos1, int &pos2){    const Lexeme &tlbrack = lex();    if (!tlbrack.is('[')) {	unlex(tlbrack);	return false;    }    pos1 = tlbrack.pos1();    const Lexeme &tword = lex();    if (tword.is(lexIdent)) {	String p = tword.string();	const char *ps = p.cc();	if (isdigit(ps[0]) || ps[0] == '-')	    port = strtol(ps, (char **)&ps, 0);	if (*ps != 0) {	    lerror(tword, "syntax error: port number should be integer");	    port = 0;	}	expect(']');	pos2 = next_pos();	return true;    } else if (tword.is(']')) {	lerror(tword, "syntax error: expected port number");	port = 0;	pos2 = tword.pos2();	return true;    } else {	lerror(tword, "syntax error: expected port number");	unlex(tword);	return false;    }}boolLexerT::yelement(int &element, bool comma_ok){    Lexeme tname = lex();    String name;    ElementClassT *etype;    int decl_pos2 = -1;    if (tname.is(lexIdent)) {	etype = element_type(tname);	name = tname.string();	decl_pos2 = tname.pos2();    } else if (tname.is('{')) {	etype = ycompound(String(), tname.pos1(), tname.pos1());	name = etype->name();	decl_pos2 = next_pos();    } else {	unlex(tname);	return false;    }        Lexeme configuration;    String lm;    const Lexeme &tparen = lex();    if (tparen.is('(')) {	lm = landmark();	// report landmark from before config string	if (!etype)	    etype = force_element_type(tname);	configuration = lex_config();	expect(')');	decl_pos2 = next_pos();    } else	unlex(tparen);    if (etype)	element = make_anon_element(tname, decl_pos2, etype, configuration.string(), lm);    else {	const Lexeme &t2colon = lex();	unlex(t2colon);	if (t2colon.is(lex2Colon) || (t2colon.is(',') && comma_ok)) {	    ydeclaration(tname);	    element = _router->eindex(name);	} else {	    element = _router->eindex(name);	    if (element < 0) {		// assume it's an element type		etype = force_element_type(tname);		element = make_anon_element(tname, tname.pos2(), etype, configuration.string(), lm);	    } else		_lexinfo->notify_element_reference(_router->element(element), tname.pos1(), tname.pos2());	}    }    return true;}voidLexerT::ydeclaration(const Lexeme &first_element){    Vector<Lexeme> decls;    Lexeme t;    if (first_element) {	decls.push_back(first_element);	goto midpoint;    }    while (true) {	t = lex();	if (!t.is(lexIdent))	    lerror(t, "syntax error: expected element name");	else	    decls.push_back(t);          midpoint:	const Lexeme &tsep = lex();	if (tsep.is(','))	    /* do nothing */;	else if (tsep.is(lex2Colon))	    break;	else {	    lerror(tsep, "syntax error: expected '::' or ','");	    unlex(tsep);	    return;	}    }    String lm = landmark();    ElementClassT *etype;    Lexeme etypet = lex();    if (etypet.is(lexIdent))	etype = force_element_type(etypet);    else if (etypet.is('{'))	etype = ycompound(String(), etypet.pos1(), etypet.pos1());    else {	lerror(etypet, "missing element type in declaration");	return;    }    Lexeme configuration;    t = lex();    if (t.is('(')) {	configuration = lex_config();	expect(')');    } else	unlex(t);    int decl_pos2 = (decls.size() == 1 ? next_pos() : -1);    for (int i = 0; i < decls.size(); i++) {	String name = decls[i].string();	if (ElementT *old_e = _router->element(name))	    ElementT::redeclaration_error(_errh, "element", name, landmark(), old_e->landmark());	else if (_router->declared_type(name) || _base_type_map[name])	    lerror(decls[i], "class '%s' used as element name", name.c_str());	else	    make_element(name, decls[i], decl_pos2, etype, configuration.string(), lm);    }}boolLexerT::yconnection(){    int element1 = -1;    int port1 = -1, port1_pos1 = -1, port1_pos2 = -1;    Lexeme t;    while (true) {	int element2;	int port2 = -1, port2_pos1, port2_pos2;	// get element	yport(port2, port2_pos1, port2_pos2);	if (!yelement(element2, element1 < 0)) {	    if (port1 >= 0)		lerror(port1_pos1, port1_pos2, "output port useless at end of chain");	    return element1 >= 0;	}	if (element1 >= 0)	    connect(element1, port1, port2, element2);	else if (port2 >= 0)	    lerror(port2_pos1, port2_pos2, "input port useless at start of chain");    	port1 = -1;          relex:	t = lex();	switch (t.kind()) {      	  case ',':	  case lex2Colon:	    if (router()->element(element2)->anonymous())		// type used as name		lerror(t, "class '%s' used as element name", router()->etype_name(element2).c_str());	    else		lerror(t, "syntax error before '%s'", t.string().c_str());	    goto relex;      	  case lexArrow:	    break;      	  case '[':	    unlex(t);	    yport(port1, port1_pos1, port1_pos2);	    goto relex;      	  case lexIdent:	  case '{':	  case '}':	  case lex2Bar:	  case lexTunnel:	  case lexElementclass:	  case lexRequire:	    unlex(t);	    // FALLTHRU	  case ';':	  case lexEOF:	    if (port1 >= 0)		lerror(port1_pos1, port1_pos2, "output port useless at end of chain", port1);	    return true;      	  default:	    lerror(t, "syntax error near '%#s'", t.string().c_str());	    if (t.kind() >= lexIdent)	// save meaningful tokens		unlex(t);	    return true;      	}    	// have 'x ->'	element1 = element2;    }}voidLexerT::yelementclass(int pos1){    Lexeme tname = lex();    String eclass_name;    if (!tname.is(lexIdent)) {	unlex(tname);	lerror(tname, "expected element type name");    } else {	String n = tname.string();	if (_router->eindex(n) >= 0)	    lerror(tname, "'%s' already used as an element name", n.cc());	else	    eclass_name = n;    }    Lexeme tnext = lex();    if (tnext.is('{'))	(void) ycompound(eclass_name, pos1, tname.pos1());    else if (tnext.is(lexIdent)) {	ElementClassT *ec = force_element_type(tnext);	if (eclass_name) {	    ElementClassT *new_ec = new SynonymElementClassT(eclass_name, ec, _router);	    _router->add_declared_type(new_ec, false);	    _lexinfo->notify_class_declaration(new_ec, false, pos1, tname.pos1(), tnext.pos2());	}	    } else	lerror(tnext, "syntax error near '%#s'", tnext.string().c_str());}voidLexerT::ytunnel(){    Lexeme tname1 = lex();    if (!tname1.is(lexIdent)) {	unlex(tname1);	lerror(tname1, "expected tunnel input name");    }        expect(lexArrow);      Lexeme tname2 = lex();    if (!tname2.is(lexIdent)) {	unlex(tname2);	lerror(tname2, "expected tunnel output name");    }      if (tname1.is(lexIdent) && tname2.is(lexIdent))	_router->add_tunnel(tname1.string(), tname2.string(), landmark(), _errh);}voidLexerT::ycompound_arguments(RouterT *comptype){  Lexeme t1, t2;    while (1) {    String vartype, varname;    // read "IDENTIFIER $VARIABLE" or "$VARIABLE"    t1 = lex();    if (t1.is(lexIdent)) {      t2 = lex();      if (t2.is(lexVariable)) {	vartype = t1.string();	varname = t2.string();      } else {	if (comptype->nformals() > 0)	  lerror(t2, "expected variable");	unlex(t2);	unlex(t1);	break;      }    } else if (t1.is(lexVariable))      varname = t1.string();    else if (t1.is('|'))      break;    else {      if (comptype->nformals() > 0)	lerror(t1, "expected variable");      unlex(t1);      break;    }    comptype->add_formal(varname, vartype);    const Lexeme &tsep = lex();    if (tsep.is('|'))      break;    else if (!tsep.is(',')) {      lerror(tsep, "expected ',' or '|'");      unlex(tsep);      break;    }  }  // check argument types  bool positional = true, error = false;  for (int i = 0; i < comptype->nformals(); i++)    if (const String &ftype = comptype->formal_types()[i]) {      positional = false;      if (ftype == "__REST__") {	if (i < comptype->nformals() - 1)	  error = true;      } else	for (int j = i + 1; j < comptype->nformals(); j++)	  if (comptype->formal_types()[j] == ftype) {	    lerror(t1, "repeated keyword parameter '%s' in compound element", ftype.c_str());	    break;	  }    } else if (!positional)      error = true;  if (error)    lerror(t1, "compound element parameters out of order\n(The correct order is '[positional], [keywords], [__REST__]'.)");}ElementClassT *LexerT::ycompound(String name, int decl_pos1, int name_pos1){    bool anonymous = (name.length() == 0);    // '{' was already read    RouterT *old_router = _router;    int old_offset = _anonymous_offset;    RouterT *first = 0, *last = 0;    ElementClassT *extension = 0;    int pos2 = name_pos1;        while (1) {	Lexeme dots = lex();	if (dots.is(lex3Dot)) {	    // '...' marks an extension type	    if (anonymous) {		lerror(dots, "cannot extend anonymous compound element class");		extension = ElementClassT::base_type("Error");	    } else {		extension = force_element_type(Lexeme(lexIdent, name, name_pos1));		_lexinfo->notify_class_extension(extension, dots.pos1(), dots.pos2());	    }	    	    dots = lex();	    if (!first || !dots.is('}'))		lerror(dots.pos1(), dots.pos2(), "'...' should occur last, after one or more compounds");	    if (dots.is('}') && first)		break;	}	unlex(dots);	// create a compound	RouterT *compound_class = new RouterT(name, landmark(), old_router);	_router = compound_class->cast_router();	_anonymous_offset = 2;	ycompound_arguments(compound_class);	while (ystatement(true))	    /* nada */;	compound_class->finish_type(_errh);	if (last)	    last->set_overload_type(compound_class);	else	    first = compound_class;	last = compound_class;	// check for '||' or '}'	const Lexeme &t = lex();	if (!t.is(lex2Bar)) {	    pos2 = t.pos2();	    break;	}    }    _anonymous_offset = old_offset;    _router = old_router;    if (extension)	last->set_overload_type(extension);    old_router->add_declared_type(first, anonymous);    _lexinfo->notify_class_declaration(first, anonymous, decl_pos1, name_pos1, pos2);    return first;}voidLexerT::yrequire(){    if (expect('(')) {	Lexeme requirement = lex_config();	expect(')');	// pre-read ';' to make it easier to write parsing extensions	expect(';', false);	Vector<String> args;	String word;	cp_argvec(requirement.string(), args);	for (int i = 0; i < args.size(); i++) {	    Vector<String> words;	    cp_spacevec(args[i], words);	    if (words.size() == 0)		/* do nothing */;	    else if (!cp_word(words[0], &word))		lerror(requirement, "bad requirement: not a word");	    else if (words.size() > 1)		lerror(requirement, "bad requirement: too many words");	    else		_router->add_requirement(word);	}    }}boolLexerT::ystatement(bool nested){  const Lexeme &t = lex();  switch (t.kind()) {       case lexIdent:   case '[':   case '{':    unlex(t);    yconnection();    return true;       case lexElementclass:    yelementclass(t.pos1());    return true;       case lexTunnel:    ytunnel();    return true;   case lexRequire:    yrequire();    return true;   case ';':    return true;       case '}':   case lex2Bar:    if (!nested)      goto syntax_error;    unlex(t);    return false;       case lexEOF:    if (nested)      lerror(t, "expected '}'");    return false;       default:   syntax_error:    lerror(t, "syntax error near '%#s'", t.string().c_str());    return true;      }}// COMPLETIONRouterT *LexerT::finish(){    RouterT *r = _router;    _router = 0;    // resolve anonymous element names    r->deanonymize_elements();    // returned router has one reference count    return r;}#include <click/vector.cc>#include <click/hashmap.cc>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -