不能分词八进制和数字类型加前/后缀的情况

拿这个词法分析器跑了一遍整个Nginx源码,基本都能正确的分出结果,后面有测试例子~

 #ifndef _STATES_H_
#define _STATES_H_ #include "log_config.h" __LOG_BEGIN_NAMESPACE enum _states
{
IN_NONE,
IN_NUM,
IN_0XNUM,
IN_INT,
IN_FLOAT,
IN_E,
IN_ALPHA,
IN_MINUS,
IN_PLUS,
IN_MULTIPLE,
IN_EXCLAMATION_POINT,
IN_AND,
IN_DIVIDE,
IN_PERCENT,
IN_LEFT_NARROW,
IN_RIGHT_NARROW,
IN_EQUAL,
IN_XOR,
IN_OR,
IN_DOT,
IN_C_COMMENT,
IN_CPP_COMMENT,
IN_FIRST_DOUBLE_QUOTATION_MARKS,
IN_SINGLE_QUOTATION_MARKS,
IN_COLON
}; __LOG_END_NAMESPACE #endif
 #ifndef _TOKEN_H_
#define _TOKEN_H_ #include <string> #include "log_config.h" __LOG_BEGIN_NAMESPACE
enum token_attr
{
NONE,//表示空属性
KEYWORD,//关键字 (if, else, ...)
INT, //整数 (1, 100, ...)
FLOAT,//浮点数 (0.1, 3.14, ...)
SYMBOL,//符号 (=, <, *, &, (, )...)
VARIABLE,//变量 (变量名, 函数名, 结构体名...)
STRING
//.......
};
struct token
{
token() :name(""), line_no(), attr(NONE) {} std::string name;
long line_no;
enum token_attr attr; void set_all(const std::string& _name,
const long _line, enum token_attr _attr)
{
set_name(_name);
set_line(_line);
set_attr(_attr);
}
void set_name(const std::string& str){ name = str; }
void set_line(const long l){ line_no = l; }
void set_attr(enum token_attr a){ attr = a; }
};
__LOG_END_NAMESPACE
#endif
 #ifndef _SCANNER_H_
#define _SCANNER_H_ #include <algorithm>
#include <string>
#include <vector> #include "log_config.h"
#include "token.h" __LOG_BEGIN_NAMESPACE
//struct token;
class scanner
{
public:
explicit scanner(const std::string& _code) :code(_code), index(), line_no() {}
//explicit scanner(const std::string& file_name, std::ifstream::openmode opm);
std::vector<token> get_all_tokens();
inline bool is_num(const char& ch);//ch是数字
inline bool is_alpha(const char& ch);//ch是字母
inline bool is_symbol(const char& ch);//ch是符号(=,<,*,&,(,)...)
inline bool is_variable(const char& ch);//ch是变量
inline char get_next_char();
inline void put_char();
private:
std::string code;
std::string::size_type index;
long line_no; std::vector<token> tok_vec;
};
__LOG_END_NAMESPACE
#endif
 #include <cctype>
#include <fstream>
#include <iostream>
#include <set> #include "keywords.h"
#include "log_config.h"
#include "scanner.h"
#include "states.h" __LOG_BEGIN_NAMESPACE std::vector<token> scanner::get_all_tokens(){
token tok;
std::string str;
long line = ;
enum _states state = IN_NONE;
char ch = get_next_char();
//跳过前导空白符
while (isblank(ch) || isspace(ch) || ch == '\n')
{
if (ch == '\n')
++line;
ch = get_next_char();
}
put_char();
//开始分词
while (){
ch = get_next_char();
if (ch == '\n' && state != IN_CPP_COMMENT)
{
++line;
continue;
}
if (ch == EOF || index == code.size())
break;
switch (state)
{
//-------------------------------------
case IN_NONE://初始状态
if (is_num(ch))
{
str = ch;
state = IN_NUM;
}
else if (is_variable(ch))
{
str = ch;
state = IN_ALPHA;
}
else if (ch == '(' || ch == ')' ||
ch == '[' || ch == ']' ||
ch == ',' || ch == '~' ||
ch == '?' || //ch == ':' ||
ch == ';' || ch == '{' ||
ch == '}' || ch == '#')
{
str = ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else if (ch == '-')
{
str = ch;
state = IN_MINUS;
}
else if (ch == '!')
{
str = ch;
state = IN_EXCLAMATION_POINT;
}
else if (ch == '+')
{
str = ch;
state = IN_PLUS;
}
else if (ch == '*')
{
str = ch;
state = IN_MULTIPLE;
}
else if (ch == '&')
{
str = ch;
state = IN_AND;
}
else if (ch == '/')
{
str = ch;
state = IN_DIVIDE;
}
else if (ch == '%')
{
str = ch;
state = IN_PERCENT;
}
else if (ch == '<')
{
str = ch;
state = IN_LEFT_NARROW;
}
else if (ch == '>')
{
str = ch;
state = IN_RIGHT_NARROW;
}
else if (ch == '=')
{
str = ch;
state = IN_EQUAL;
}
else if (ch == '^')
{
str = ch;
state = IN_XOR;
}
else if (ch == '|')
{
str = ch;
state = IN_OR;
}
else if (ch == '.')
{
str = ch;
state = IN_DOT;
}
else if (ch == '"')
{
str = ch;
state = IN_FIRST_DOUBLE_QUOTATION_MARKS;
}
else if (ch == ':')
{
str = ch;
state = IN_COLON;
}
else if (ch == '\'')
{
str = ch;
state = IN_SINGLE_QUOTATION_MARKS;
}
break;
//-------------------------------------
case IN_NUM:
if (is_num(ch))
{
str += ch;
state = IN_NUM;
}
else if (ch == 'e' || ch == 'E')
{
str += ch;
state = IN_E;
}
else if (ch == '.')
{
str += ch;
state = IN_DOT;
}
else
{
if (str == "" && (ch == 'X' || ch == 'x'))
{
str += ch;
state = IN_0XNUM;
}
else
{
put_char();
tok.set_all(str, line, INT);
this->tok_vec.push_back(tok);
state = IN_NONE;
}
}
break;
//-------------------------------------
case IN_0XNUM:
if (is_num(ch) ||
(ch >= 'A' && ch <= 'F') ||
(ch >= 'a' && ch <= 'f'))
{
str += ch;
state = IN_0XNUM;
}
else
{
put_char();
tok.set_all(str, line, INT);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//-------------------------------------
case IN_E:
if (ch == '-')
{
str += ch;
state = IN_MINUS;
}
else if (ch == '+')
{
str += ch;
state = IN_PLUS;
}
else if (is_num(ch))
{
str += ch;
state = IN_NUM;
}
break;
//-------------------------------------
case IN_ALPHA:
if (is_alpha(ch) || is_num(ch) || ch == '_')
{
str += ch;
state = IN_ALPHA;
}
else
{
put_char();
if (keywords.find(str) == keywords.end())
{
tok.set_all(str, line, VARIABLE);
}
else
{
tok.set_all(str, line, KEYWORD);
}
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//-------------------------------------
case IN_MINUS:
if (ch == '>')
{// ->
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else if (ch == '-')
{// --
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else if (ch == '=')
{// -=
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else if (is_num(ch))
{//负数
str += ch;
state = IN_NUM;
}
else
{//'-'
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//-------------------------------------
case IN_EXCLAMATION_POINT:
if (ch == '=')
{ // !=
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else
{//'!'
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//------------------------------
case IN_PLUS:
if (ch == '+')
{// ++
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else if (ch == '=')
{// +=
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else if (is_num(ch))
{//正数
str += ch;
state = IN_NUM;
}
else
{//'+'
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//-------------------------
case IN_MULTIPLE:
if (ch == '=')
{// *=
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else
{//'*'
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//---------------------
case IN_AND:
if (ch == '&')
{// &&
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else if (ch == '=')
{// &=
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else
{// &
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//---------------------
case IN_DIVIDE:
if (ch == '=')
{// /=
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else if (ch == '/')
{// //
str.clear();
state = IN_CPP_COMMENT;
}
else if (ch == '*')
{// /*
str.clear();
state = IN_C_COMMENT;
}
else
{// /
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//----------------------------
case IN_C_COMMENT:
if (ch == '*')
{
ch = get_next_char();
if (ch == '/')
{
state = IN_NONE;
continue;
}
else
{
state = IN_C_COMMENT;
}
}
else
{
state = IN_C_COMMENT;
}
break;
//----------------------------
case IN_CPP_COMMENT:
if (ch == '\n')
{
put_char();
state = IN_NONE;
}
else
{
state = IN_CPP_COMMENT;
}
break;
//----------------------------
case IN_PERCENT:
if (ch == '=')
{// %=
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else
{// %
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//------------------------
case IN_LEFT_NARROW:
if (ch == '<')
{// <<
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else if (ch == '=')
{// <=
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else
{// <
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//------------------------
case IN_RIGHT_NARROW:
if (ch == '>')
{// >>
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else if (ch == '=')
{// >=
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else
{// >
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//----------------------------
case IN_EQUAL:
if (ch == '=')
{// ==
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else
{// =
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//-------------------------
case IN_XOR:
if (ch == '=')
{// ^=
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else
{// ^
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//---------------------------
case IN_OR:
if (ch == '|')
{// ||
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else if (ch == '=')
{// |=
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else
{// |
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//---------------------
case IN_DOT:
if (is_num(ch))
{
str += ch;
state = IN_NUM;
}
else
{
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//-------------------
case IN_FIRST_DOUBLE_QUOTATION_MARKS:
if (ch == '\\')
{//遇到转义符
str += ch;
ch = get_next_char();
if (ch == '"')
{
str += ch;
}
else
{
put_char();
}
state = IN_FIRST_DOUBLE_QUOTATION_MARKS;
}
else if (ch == '"')
{
str += ch;
tok.set_all(str, line, STRING);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else
{
str += ch;
state = IN_FIRST_DOUBLE_QUOTATION_MARKS;
}
break;
//---------------------------
case IN_COLON:
if (ch == ':')
{
str += ch;
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
else
{
put_char();
tok.set_all(str, line, SYMBOL);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//--------------------------
case IN_SINGLE_QUOTATION_MARKS:
if (ch != '\'')
{
str += ch;
state = IN_SINGLE_QUOTATION_MARKS;
}
else
{
str += ch;
tok.set_all(str, line, STRING);
this->tok_vec.push_back(tok);
str.clear();
state = IN_NONE;
}
break;
//--------------------------
default:
break;
}// switch
}// while
return std::move(tok_vec);
} bool scanner::is_alpha(const char& ch)
{
if ((ch >= 'A' && ch <= 'Z') ||
(ch >= 'a' && ch <= 'z'))
return true;
return false;
}
bool scanner::is_num(const char& ch)
{
if (ch >= '' && ch <= '')
return true;
return false;
}
bool scanner::is_variable(const char& ch)
{
if (ch == '_' || is_alpha(ch))
return true;
return false;
}
char scanner::get_next_char()
{
return code[index++];
}
void scanner::put_char()
{
--index;
}
//scanner::scanner(const std::string& file_name, std::ifstream::openmode opm)
//{
// std::ifstream ifs;
// ifs.open(file_name, opm);
// if (ifs)
// {
// ifs.seekg(0, ifs.end);
// std::size_t len = ifs.tellg();
// ifs.seekg(0, ifs.beg);
// code.resize(len + 1);
// ifs.read((char*)&*(code.begin()), len);
// code[len ] = '\0';
//
//
// std::cout << code << std::endl;
// }
// ifs.close();
//}
__LOG_END_NAMESPACE

测试如下:

 #include <iostream>
#include <vector>
#include <fstream> #include "scanner.h" using namespace std;
int main()
{
string file_name("C:\\Users\\zxh\\Desktop\\test1.c");
ofstream ofs("C:\\Users\\zxh\\Desktop\\result.c");
std::ifstream ifs;
ifs.open(file_name, ifstream::binary);
if (ifs)
{
ifs.seekg(, ifs.end);
std::size_t len = ifs.tellg();
ifs.seekg(, ifs.beg);
string _code;
_code.resize(len + );
ifs.read((char*)&*(_code.begin()), len);
_code[len + ] = '\0';
ifs.close();
scanner s(_code);
vector<token> v = s.get_all_tokens();
for (const auto s : v)
{
ofs << s.name << " " << s.line_no << " "; }
}
system("pause");
return ;
}

分词的代码选取为Nginx源码下的一个函数

 static ngx_int_t
ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
{
int events;
uint32_t revents;
ngx_int_t instance, i;
ngx_uint_t level;
ngx_err_t err;
ngx_event_t *rev, *wev, **queue;
ngx_connection_t *c; int i = 0XFFFFFFFF, 0X1234defc, 0x3333; /* NGX_TIMER_INFINITE == INFTIM */ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, ,
"epoll timer: %M", timer); events = epoll_wait(ep, event_list, (int) nevents, timer); err = (events == -) ? ngx_errno : ; if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
ngx_time_update();
} if (err) {
if (err == NGX_EINTR) { if (ngx_event_timer_alarm) {
ngx_event_timer_alarm = ;
return NGX_OK;
} level = NGX_LOG_INFO; } else {
level = NGX_LOG_ALERT;
} ngx_log_error(level, cycle->log, err, "epoll_wait() failed");
return NGX_ERROR;
} if (events == ) {
if (timer != NGX_TIMER_INFINITE) {
return NGX_OK;
} ngx_log_error(NGX_LOG_ALERT, cycle->log, ,
"epoll_wait() returned no events without timeout");
return NGX_ERROR;
} ngx_mutex_lock(ngx_posted_events_mutex); for (i = ; i < events; i++) {
c = event_list[i].data.ptr; instance = (uintptr_t) c & ;
c = (ngx_connection_t *) ((uintptr_t) c & (uintptr_t) ~); rev = c->read; if (c->fd == - || rev->instance != instance) { /*
* the stale event from a file descriptor
* that was just closed in this iteration
*/ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, ,
"epoll: stale event %p", c);
continue;
} revents = event_list[i].events; ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, ,
"epoll: fd:%d ev:%04XD d:%p",
c->fd, revents, event_list[i].data.ptr); if (revents & (EPOLLERR|EPOLLHUP)) {
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, ,
"epoll_wait() error on fd:%d ev:%04XD",
c->fd, revents);
} #if 0
if (revents & ~(EPOLLIN|EPOLLOUT|EPOLLERR|EPOLLHUP)) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ,
"strange epoll_wait() events fd:%d ev:%04XD",
c->fd, revents);
}
#endif if ((revents & (EPOLLERR|EPOLLHUP))
&& (revents & (EPOLLIN|EPOLLOUT)) == )
{
/*
* if the error events were returned without EPOLLIN or EPOLLOUT,
* then add these flags to handle the events at least in one
* active handler
*/ revents |= EPOLLIN|EPOLLOUT;
} if ((revents & EPOLLIN) && rev->active) { #if (NGX_HAVE_EPOLLRDHUP)
if (revents & EPOLLRDHUP) {
rev->pending_eof = ;
}
#endif if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
rev->posted_ready = ; } else {
rev->ready = ;
} if (flags & NGX_POST_EVENTS) {
queue = (ngx_event_t **) (rev->accept ?
&ngx_posted_accept_events : &ngx_posted_events); ngx_locked_post_event(rev, queue); } else {
rev->handler(rev);
}
} wev = c->write; if ((revents & EPOLLOUT) && wev->active) { if (c->fd == - || wev->instance != instance) { /*
* the stale event from a file descriptor
* that was just closed in this iteration
*/ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, ,
"epoll: stale event %p", c);
continue;
} if (flags & NGX_POST_THREAD_EVENTS) {
wev->posted_ready = ; } else {
wev->ready = ;
} if (flags & NGX_POST_EVENTS) {
ngx_locked_post_event(wev, &ngx_posted_events); } else {
wev->handler(wev);
}
}
} ngx_mutex_unlock(ngx_posted_events_mutex); return NGX_OK;
}

分词结果如下

 static
ngx_int_t
ngx_epoll_process_events
(
ngx_cycle_t
*
cycle
,
ngx_msec_t
timer
,
ngx_uint_t
flags
)
{
int
events
;
uint32_t
revents
;
ngx_int_t
instance
,
i
;
ngx_uint_t
level
;
ngx_err_t
err
;
ngx_event_t
*
rev
,
*
wev
,
*
*
queue
;
ngx_connection_t
*
c
;
int
i
=
0XFFFFFFFF
,
0X1234defc
,
0x3333
;
ngx_log_debug1
(
NGX_LOG_DEBUG_EVENT
,
cycle
->
log
, ,
"epoll timer: %M"
,
timer
)
;
events
=
epoll_wait
(
ep
,
event_list
,
(
int
)
nevents
,
timer
)
;
err
=
(
events
==
-
)
?
ngx_errno
: ;
if
(
flags
&
NGX_UPDATE_TIME
||
ngx_event_timer_alarm
)
{
ngx_time_update
(
)
;
}
if
(
err
)
{
if
(
err
==
NGX_EINTR
)
{
if
(
ngx_event_timer_alarm
)
{
ngx_event_timer_alarm
= ;
return
NGX_OK
;
}
level
=
NGX_LOG_INFO
;
}
else
{
level
=
NGX_LOG_ALERT
;
}
ngx_log_error
(
level
,
cycle
->
log
,
err
,
"epoll_wait() failed"
)
;
return
NGX_ERROR
;
}
if
(
events
== )
{
if
(
timer
!=
NGX_TIMER_INFINITE
)
{
return
NGX_OK
;
}
ngx_log_error
(
NGX_LOG_ALERT
,
cycle
->
log
, ,
"epoll_wait() returned no events without timeout"
)
;
return
NGX_ERROR
;
}
ngx_mutex_lock
(
ngx_posted_events_mutex
)
;
for
(
i
= ;
i
<
events
;
i
++
)
{
c
=
event_list
[
i
]
.
data
.
ptr
;
instance
=
(
uintptr_t
)
c
& ;
c
=
(
ngx_connection_t
*
)
(
(
uintptr_t
)
c
&
(
uintptr_t
)
~ )
;
rev
=
c
->
read
;
if
(
c
->
fd
==
-
||
rev
->
instance
!=
instance
)
{
ngx_log_debug1
(
NGX_LOG_DEBUG_EVENT
,
cycle
->
log
, ,
"epoll: stale event %p"
,
c
)
;
continue
;
}
revents
=
event_list
[
i
]
.
events
;
ngx_log_debug3
(
NGX_LOG_DEBUG_EVENT
,
cycle
->
log
, ,
"epoll: fd:%d ev:%04XD d:%p"
,
c
->
fd
,
revents
,
event_list
[
i
]
.
data
.
ptr
)
;
if
(
revents
&
(
EPOLLERR
|
EPOLLHUP
)
)
{
ngx_log_debug2
(
NGX_LOG_DEBUG_EVENT
,
cycle
->
log
, ,
"epoll_wait() error on fd:%d ev:%04XD"
,
c
->
fd
,
revents
)
;
}
#
if if
(
revents
&
~
(
EPOLLIN
|
EPOLLOUT
|
EPOLLERR
|
EPOLLHUP
)
)
{
ngx_log_error
(
NGX_LOG_ALERT
,
cycle
->
log
, ,
"strange epoll_wait() events fd:%d ev:%04XD"
,
c
->
fd
,
revents
)
;
}
#
endif
if
(
(
revents
&
(
EPOLLERR
|
EPOLLHUP
)
)
&&
(
revents
&
(
EPOLLIN
|
EPOLLOUT
)
)
== )
{
revents
|=
EPOLLIN
|
EPOLLOUT
;
}
if
(
(
revents
&
EPOLLIN
)
&&
rev
->
active
)
{
#
if
(
NGX_HAVE_EPOLLRDHUP
)
if
(
revents
&
EPOLLRDHUP
)
{
rev
->
pending_eof
= ;
}
#
endif
if
(
(
flags
&
NGX_POST_THREAD_EVENTS
)
&&
!
rev
->
accept
)
{
rev
->
posted_ready
= ;
}
else
{
rev
->
ready
= ;
}
if
(
flags
&
NGX_POST_EVENTS
)
{
queue
=
(
ngx_event_t
*
*
)
(
rev
->
accept
?
&
ngx_posted_accept_events
:
&
ngx_posted_events
)
;
ngx_locked_post_event
(
rev
,
queue
)
;
}
else
{
rev
->
handler
(
rev
)
;
}
}
wev
=
c
->
write
;
if
(
(
revents
&
EPOLLOUT
)
&&
wev
->
active
)
{
if
(
c
->
fd
==
-
||
wev
->
instance
!=
instance
)
{
ngx_log_debug1
(
NGX_LOG_DEBUG_EVENT
,
cycle
->
log
, ,
"epoll: stale event %p"
,
c
)
;
continue
;
}
if
(
flags
&
NGX_POST_THREAD_EVENTS
)
{
wev
->
posted_ready
= ;
}
else
{
wev
->
ready
= ;
}
if
(
flags
&
NGX_POST_EVENTS
)
{
ngx_locked_post_event
(
wev
,
&
ngx_posted_events
)
;
}
else
{
wev
->
handler
(
wev
)
;
}
}
}
ngx_mutex_unlock
(
ngx_posted_events_mutex
)
;
return
NGX_OK
;
}

兼容90%标准C的词法分析器的更多相关文章

  1. 怎样写一个与Windows10 IE11兼容的标准BHO?

    p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; f ...

  2. 怎样写一个与Win8 IE11兼容的标准BHO?

    怎样写一个与Win8 IE11兼容的标准BHO? 环境:Windows8.1 x86 IE11(其它环境未讨论) 作者:magictong 日期:2014/02/02 概述 微软在2013年6月份推出 ...

  3. selenium兼容非标准chrome内核的浏览器

    多浏览器兼容性测试(1) RIDE已经支持多浏览器兼容性测试,例如: firefox ie chrome safari 但是,项目要求支持360极速和360安全浏览器.所以,我们需要增加代码让RIDE ...

  4. APUE之第5章——标准I/O库

    一.知识回顾:文件I/O 文件 I/O 是不带缓冲的 I/O(unbuffered I/O),指每个 read 和 write 都调用内核中的一个系统调用. 对于内核而言,所有打开的文件都通过文件描述 ...

  5. GB∕T 35658平台过检 已通过最新的部标JT/T 808-2019, JT/T 809-2019标准检测

    2019年交通部GPS平台检测标准发生了重大变化, 原来的796平台功能标准, 变更为GB/T35658标准, 这个标准其实2017年就公布了, 实际上还是796标准, 但是检测项目,以前是可选的, ...

  6. [C] zlstdint(让VC、TC等编译器自动兼容C99的整数类型)V1.0。支持Turbo C++ 3等DOS下的编译器

    作者:zyl910 以前我曾为了让VC++等编译器支持C99的整数类型,便编写了c99int库来智能处理(http://www.cnblogs.com/zyl910/p/c99int_v102.htm ...

  7. html设置360兼容/极速模式

    由于众所周知的情况,国内的主流浏览器都是双核浏览器:基于Webkit内核用于常用网站的高速浏览.基于IE的内核用于兼容网银.旧版网站.以360的几款浏览器为例,我们优先通过Webkit内核渲染主流的网 ...

  8. stm32开发之标准库的介绍

    1 STM32标准外设库概述 STM32标准外设库之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序.数据结构和宏组成,包括了微控制器所有外设的性能特征.该函数库还包括每一个外设的驱动描 ...

  9. 文件IO和标准IO的区别【转】

    一.先来了解下什么是文件I/O和标准I/O: 文件I/O:文件I/O称之为不带缓存的IO(unbuffered I/O).不带缓存指的是每个read,write都调用内核中的一个系统调用.也就是一般所 ...

随机推荐

  1. 『TCP/IP详解——卷一:协议』读书笔记——17

    2013-08-27 15:37:42 6.5 ICMP端口不可达差错 端口不可达报文是ICMP差错报文的一种,它是ICMP不可达报文中的一种,以此来看一看ICMP差错报文中所附加的信息.使用UDP来 ...

  2. surface上的手势事件

    surface上的手势事件 1.surface上的触控事件测试. 手指触控在CHROME和FIREFOX下会触发touch事件,而IE10是不支持touch事件的. 手指触控在三个浏览器下均会触发全部 ...

  3. PROC SORT

    PROC SORT DATA=输入数据集 <OUT=输出数据集><选项>; BY 关键变量; RUN; PROC SORT 语法如上,其中在尖括号中的可以不出现,也不会报错. ...

  4. 萝卜白菜,给有所爱——C#和JAVA都会终将被时代淘汰

    看到园子里又有一波试图掀起C#和JAVA的谁更好的争论,对于这些一直不断的争论,我觉得实在没有必要,黑格尔的存在即合理,中国的老古语说的萝卜白菜各有所爱,大家争论的再多其实卵用也没用,还不如趁着闲暇时 ...

  5. 简单的OkHttp使用介绍

    Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient.关于HttpURLConnection和HttpClient的选择>>官方博客尽管Go ...

  6. asp.net中gridview的checkbox使用总结

    1.在gridview中的<column>中加入 <asp:TemplateField HeaderText="选择"> <ItemTemplate& ...

  7. 使用UG UISTYLER 窗体编辑器,创建对话框 part 1

    在UG 二次开发中,经常需要一些交互的输入,参数的更改啊,零件的选取什么的,UG 自身提供了创建这一类对话框的功能.当然也可以使用MFC或winForm 作为交互.但使用自带的比较快和简洁,风格也统一 ...

  8. c# 列举所有窗口和子窗口

    private delegate bool WNDENUMPROC(IntPtr hWnd, int lParam); [DllImport("user32.dll", Exact ...

  9. linux redmine 搭建

    redmine搭建过程参考:http://www.tuicool.com/articles/InMbym 注意事项: 配置文件必须以2个空格开始 启动(指定了端口,和绑定的IP): ruby bin/ ...

  10. 配置tomcat编码格式

    tomcat默认编码格式为“ISO-8859-1”,打开tomcat的“server.xml”文件,找到下面行并修改 <Connector connectionTimeout="200 ...