Add /s modifier to parser for patterns

This commit is contained in:
Tim Wojtulewicz 2022-07-12 16:22:29 -07:00
parent 14e48733ac
commit 36e31e28ac
2 changed files with 30 additions and 5 deletions

View file

@ -54,7 +54,7 @@
%left '$' '[' ']' '(' ')' TOK_HAS_FIELD TOK_HAS_ATTR %left '$' '[' ']' '(' ')' TOK_HAS_FIELD TOK_HAS_ATTR
%nonassoc TOK_AS TOK_IS %nonassoc TOK_AS TOK_IS
%type <b> opt_no_test opt_no_test_block TOK_PATTERN_END opt_deep when_flavor %type <b> opt_no_test opt_no_test_block opt_deep when_flavor
%type <str> TOK_ID TOK_PATTERN_TEXT %type <str> TOK_ID TOK_PATTERN_TEXT
%type <id> local_id global_id def_global_id event_id global_or_event_id resolve_id begin_lambda case_type %type <id> local_id global_id def_global_id event_id global_or_event_id resolve_id begin_lambda case_type
%type <id_l> local_id_list case_type_list %type <id_l> local_id_list case_type_list
@ -77,6 +77,7 @@
%type <capture> capture %type <capture> capture
%type <captures> capture_list opt_captures when_captures %type <captures> capture_list opt_captures when_captures
%type <when_clause> when_head when_start when_clause %type <when_clause> when_head when_start when_clause
%type <re_modes> TOK_PATTERN_END
%{ %{
#include <cstdlib> #include <cstdlib>
@ -324,6 +325,11 @@ static StmtPtr build_local(ID* id, Type* t, InitClass ic, Expr* e,
zeek::FuncType::Capture* capture; zeek::FuncType::Capture* capture;
zeek::FuncType::CaptureList* captures; zeek::FuncType::CaptureList* captures;
zeek::detail::WhenInfo* when_clause; zeek::detail::WhenInfo* when_clause;
struct
{
bool ignore_case;
bool single_line;
} re_modes;
} }
%% %%
@ -912,9 +918,13 @@ expr:
auto* re = new RE_Matcher($3); auto* re = new RE_Matcher($3);
delete [] $3; delete [] $3;
if ( $4 ) if ( $4.ignore_case )
re->MakeCaseInsensitive(); re->MakeCaseInsensitive();
if ( $4.single_line )
{
}
re->Compile(); re->Compile();
$$ = new ConstExpr(make_intrusive<PatternVal>(re)); $$ = new ConstExpr(make_intrusive<PatternVal>(re));
} }

View file

@ -562,13 +562,28 @@ F RET_CONST(zeek::val_mgr->False()->Ref())
<RE>"/" { <RE>"/" {
BEGIN(INITIAL); BEGIN(INITIAL);
yylval.b = false; yylval.re_modes.ignore_case = false;
yylval.re_modes.single_line = false;
return TOK_PATTERN_END; return TOK_PATTERN_END;
} }
<RE>"/i" { <RE>(\/[is]{0,2}) {
BEGIN(INITIAL); BEGIN(INITIAL);
yylval.b = true;
if (strlen(yytext) == 2)
{
yylval.re_modes.ignore_case = (yytext[1] == 'i');
yylval.re_modes.single_line = (yytext[1] == 's');
}
else
{
if ( yytext[1] == yytext[2] )
zeek::reporter->Error("pattern has duplicate mode %c", yytext[1]);
yylval.re_modes.ignore_case = (yytext[1] == 'i' || yytext[2] == 'i');
yylval.re_modes.single_line = (yytext[1] == 's' || yytext[2] == 's');
}
return TOK_PATTERN_END; return TOK_PATTERN_END;
} }