mirror of
https://github.com/cwbaker/lalr.git
synced 2026-09-26 16:33:18 +03:00
Allow most metacharacters in character classes, e.g. allow "[+-]"
Allows most metacharacters, e.g. "*+()[", to appear unescaped within a character class. This, along with hyphens at the end, allows "[+-]" to match a plus or a minus.
This commit is contained in:
parent
2235e9fe6b
commit
aaea898aab
3 changed files with 43 additions and 4 deletions
|
|
@ -241,7 +241,7 @@ bool RegexParser::match_item()
|
|||
syntax_tree_->item_xdigit();
|
||||
return true;
|
||||
}
|
||||
else if ( match_character() )
|
||||
else if ( match_character_in_character_class() )
|
||||
{
|
||||
int character = escape( lexeme_begin_, lexeme_end_ );
|
||||
if ( match_end_of_range() )
|
||||
|
|
@ -325,7 +325,7 @@ bool RegexParser::match_negative_item()
|
|||
syntax_tree_->negative_item_xdigit();
|
||||
return true;
|
||||
}
|
||||
else if ( match_character() )
|
||||
else if ( match_character_in_character_class() )
|
||||
{
|
||||
int character = escape( lexeme_begin_, lexeme_end_ );
|
||||
if ( match_end_of_range() )
|
||||
|
|
@ -344,6 +344,17 @@ bool RegexParser::match_negative_item()
|
|||
|
||||
bool RegexParser::match_character()
|
||||
{
|
||||
return match_character( "|*+?[]()-" );
|
||||
}
|
||||
|
||||
bool RegexParser::match_character_in_character_class()
|
||||
{
|
||||
return match_character( "^]-" );
|
||||
}
|
||||
|
||||
bool RegexParser::match_character( const char* metacharacters )
|
||||
{
|
||||
LALR_ASSERT( metacharacters );
|
||||
const char* position = position_;
|
||||
if ( position != end_ )
|
||||
{
|
||||
|
|
@ -375,7 +386,7 @@ bool RegexParser::match_character()
|
|||
position_ = position;
|
||||
return true;
|
||||
}
|
||||
else if ( !strchr("|*+?[]()-", *position) )
|
||||
else if ( !strchr(metacharacters, *position) )
|
||||
{
|
||||
++position;
|
||||
lexeme_begin_ = position_;
|
||||
|
|
@ -390,7 +401,7 @@ bool RegexParser::match_character()
|
|||
bool RegexParser::match_end_of_range()
|
||||
{
|
||||
const char* position = position_;
|
||||
if ( match("-") && match_character() )
|
||||
if ( match("-") && match_character_in_character_class() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@ private:
|
|||
bool match_item();
|
||||
bool match_negative_item();
|
||||
bool match_character();
|
||||
bool match_character_in_character_class();
|
||||
bool match_character( const char* metacharacters );
|
||||
bool match_bracket_expression_character();
|
||||
bool match_end_of_range();
|
||||
bool match_identifier();
|
||||
bool match( const char* lexeme );
|
||||
|
|
|
|||
|
|
@ -1378,4 +1378,29 @@ SUITE( RegularExpressions )
|
|||
CHECK_EQUAL( "NOT BETWEEN", lexer.lexeme() );
|
||||
CHECK( lexer.symbol() == ¬_between );
|
||||
}
|
||||
|
||||
|
||||
TEST( CharacterClassHyphens )
|
||||
{
|
||||
void* plus_or_minus;
|
||||
RegexCompiler compiler;
|
||||
compiler.compile( "[+-]", &plus_or_minus );
|
||||
Lexer<const char*> lexer( compiler.state_machine() );
|
||||
|
||||
const char* regex = "+";
|
||||
lexer.reset( regex, regex + strlen(regex) );
|
||||
lexer.advance();
|
||||
CHECK( lexer.symbol() == &plus_or_minus );
|
||||
CHECK( lexer.lexeme() == "+" );
|
||||
lexer.advance();
|
||||
CHECK( lexer.symbol() == nullptr );
|
||||
|
||||
regex = "-";
|
||||
lexer.reset( regex, regex + strlen(regex) );
|
||||
lexer.advance();
|
||||
CHECK( lexer.symbol() == &plus_or_minus );
|
||||
CHECK( lexer.lexeme() == "-" );
|
||||
lexer.advance();
|
||||
CHECK( lexer.symbol() == nullptr );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue