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

📄 lexert.cc

📁 Click is a modular router toolkit. To use it you ll need to know how to compile and install the sof
💻 CC
📖 第 1 页 / 共 2 页
字号:
	    lerror(location, "element name %<%s%> has all-digit component", name.c_str());	    break;	}    }    const char *end_decl = (decl_pos2 ? decl_pos2 : location.pos2());    ElementT *e = _router->get_element(name, type, conf, landmarkt(location.pos1(), location.pos2()));    _lexinfo->notify_element_declaration(e, location.pos1(), location.pos2(), end_decl);    return e->eindex();}intLexerT::make_anon_element(const Lexeme &what, const char *decl_pos2,			  ElementClassT *type, const String &conf){    return make_element(anon_element_name(type->name()), what, decl_pos2, type, conf);}voidLexerT::connect(int element1, int port1, int port2, int element2, const char *pos1, const char *pos2){    if (port1 < 0)	port1 = 0;    if (port2 < 0)	port2 = 0;    _router->add_connection	(PortT(_router->element(element1), port1),	 PortT(_router->element(element2), port2), landmarkt(pos1, pos2));}// PARSINGboolLexerT::yport(int &port, const char *&pos1, const char *&pos2){    const Lexeme &tlbrack = lex();    pos1 = tlbrack.pos1();    if (!tlbrack.is('[')) {	unlex(tlbrack);	pos2 = pos1;	return false;    }    const Lexeme &tword = lex();    if (tword.is(lexIdent)) {	String p = tword.string();	const char *ps = p.c_str();	if (isdigit((unsigned char) 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;    const char *decl_pos2 = 0;    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;    const Lexeme &tparen = lex();    if (tparen.is('(')) {	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());    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());	    } 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;	}    }    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);    const char *decl_pos2 = (decls.size() == 1 ? next_pos() : 0);    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.get(name))	    lerror(decls[i], "class %<%s%> used as element name", name.c_str());	else	    make_element(name, decls[i], decl_pos2, etype, configuration.string());    }}boolLexerT::yconnection(){    int element1 = -1, port1 = -1;    const char *last_element_pos = next_pos(), *port1_pos1 = 0, *port1_pos2 = 0;    Lexeme t;    while (true) {	int element2, port2 = -1;	const char *port2_pos1, *port2_pos2, *next_element_pos;	// get element	yport(port2, port2_pos1, port2_pos2);	next_element_pos = next_pos();	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, last_element_pos, next_pos());	else if (port2 >= 0)	    lerror(port2_pos1, port2_pos2, "input port useless at start of chain");	port1 = -1;	port1_pos1 = port1_pos2 = 0;	last_element_pos = next_element_pos;      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 lexElementclass:	  case lexRequire:	  case lexDefine:	    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(const char *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.c_str());	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::ydefine(RouterT *r, const String &fname, const String &ftype, bool isformal, const Lexeme &t, bool &scope_order_error){    if (!r->define(fname, ftype, isformal))	lerror(t, "parameter %<$%s%> multiply defined", fname.c_str());    else if (isformal) {	if (ftype)	    for (int i = 0; i < r->scope().size() - 1; i++)		if (r->scope().value(i) == ftype) {		    lerror(t, "repeated keyword parameter %<%s%> in compound element", ftype.c_str());		    break;		}	if (!scope_order_error && r->nformals() > 1	    && ((!ftype && r->scope().value(r->nformals() - 2))		|| r->scope().value(r->nformals() - 2) == "__REST__")) {	    lerror(t, "compound element parameters out of order\n(The correct order is %<[positional], [keywords], [__REST__]%>.)");	    scope_order_error = true;	}    }}voidLexerT::ycompound_arguments(RouterT *comptype){  Lexeme t1, t2;  bool scope_order_error = false;  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;    }    ydefine(comptype, varname, vartype, true, t1, scope_order_error);    const Lexeme &tsep = lex();    if (tsep.is('|'))      break;    else if (!tsep.is(',')) {      lerror(tsep, "expected %<,%> or %<|%>");      unlex(tsep);      break;    }  }}ElementClassT *LexerT::ycompound(String name, const char *decl_pos1, const char *name_pos1){    bool anonymous = (name.length() == 0);    String printable_name = name;    if (anonymous)	printable_name = "<anonymous" + String(++_anonymous_class_count) + ">";    // '{' was already read    RouterT *old_router = _router;    int old_offset = _anonymous_offset;    RouterT *first = 0, *last = 0;    ElementClassT *extension = 0;    const char *class_pos1 = name_pos1;    const char *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, landmarkt(class_pos1, dots.pos1()), old_router);	compound_class->set_printable_name(printable_name);	_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();	compound_class->set_landmarkt(landmarkt(class_pos1, t.pos2()));	class_pos1 = t.pos1();	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);	}    }}voidLexerT::yvar(){    if (expect('(')) {	Lexeme vars = lex_config();	expect(')');	Vector<String> args;	String word;	cp_argvec(vars.string(), args);	for (int i = 0; i < args.size(); i++)	    if (args[i]) {		String var = cp_shift_spacevec(args[i]);		const char *s = var.begin();		if (s != var.end() && *s == '$')		    for (s++; s != var.end() && (isalnum((unsigned char) *s) || *s == '_'); s++)			/* nada */;		if (var.length() < 2 || s != var.end())		    lerror(vars, "bad %<var%> declaration: not a variable");		else {		    var = var.substring(1);		    if (!_router->define(var, args[i], false))			lerror(vars, "parameter %<%s%> multiply defined", var.c_str());		}	    }    }}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 lexRequire:    yrequire();    return true;   case lexDefine:    yvar();    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(const VariableEnvironment &global_scope){    RouterT *r = _router;    _router = 0;    r->redefine(global_scope);    // resolve anonymous element names    r->deanonymize_elements();    // returned router has one reference count    return r;}

⌨️ 快捷键说明

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