📄 parse.y
字号:
trlcontxt = true;
eps = mkstate( SYM_EPSILON );
$$ = link_machines( $1,
link_machines( eps, mkstate( '\n' ) ) );
}
| re
{
$$ = $1;
if ( trlcontxt )
{
if ( lex_compat || (varlength && headcnt == 0) )
/* Both head and trail are
* variable-length.
*/
variable_trail_rule = true;
else
trailcnt = rulelen;
}
}
;
re : re '|' series
{
varlength = true;
$$ = mkor( $1, $3 );
}
| series
{ $$ = $1; }
;
re2 : re '/'
{
/* This rule is written separately so the
* reduction will occur before the trailing
* series is parsed.
*/
if ( trlcontxt )
synerr( "trailing context used twice" );
else
trlcontxt = true;
if ( varlength )
/* We hope the trailing context is
* fixed-length.
*/
varlength = false;
else
headcnt = rulelen;
rulelen = 0;
current_state_type = STATE_TRAILING_CONTEXT;
$$ = $1;
}
;
series : series singleton
{
/* This is where concatenation of adjacent patterns
* gets done.
*/
$$ = link_machines( $1, $2 );
}
| singleton
{ $$ = $1; }
;
singleton : singleton '*'
{
varlength = true;
$$ = mkclos( $1 );
}
| singleton '+'
{
varlength = true;
$$ = mkposcl( $1 );
}
| singleton '?'
{
varlength = true;
$$ = mkopt( $1 );
}
| singleton '{' NUMBER ',' NUMBER '}'
{
varlength = true;
if ( $3 > $5 || $3 < 0 )
{
synerr( "bad iteration values" );
$$ = $1;
}
else
{
if ( $3 == 0 )
{
if ( $5 <= 0 )
{
synerr(
"bad iteration values" );
$$ = $1;
}
else
$$ = mkopt(
mkrep( $1, 1, $5 ) );
}
else
$$ = mkrep( $1, $3, $5 );
}
}
| singleton '{' NUMBER ',' '}'
{
varlength = true;
if ( $3 <= 0 )
{
synerr( "iteration value must be positive" );
$$ = $1;
}
else
$$ = mkrep( $1, $3, INFINITY );
}
| singleton '{' NUMBER '}'
{
/* The singleton could be something like "(foo)",
* in which case we have no idea what its length
* is, so we punt here.
*/
varlength = true;
if ( $3 <= 0 )
{
synerr( "iteration value must be positive" );
$$ = $1;
}
else
$$ = link_machines( $1,
copysingl( $1, $3 - 1 ) );
}
| '.'
{
if ( ! madeany )
{
/* Create the '.' character class. */
anyccl = cclinit();
ccladd( anyccl, '\n' );
cclnegate( anyccl );
if ( useecs )
mkeccl( ccltbl + cclmap[anyccl],
ccllen[anyccl], nextecm,
ecgroup, csize, csize );
madeany = true;
}
++rulelen;
$$ = mkstate( -anyccl );
}
| fullccl
{
if ( ! cclsorted )
/* Sort characters for fast searching. We
* use a shell sort since this list could
* be large.
*/
cshell( ccltbl + cclmap[$1], ccllen[$1], true );
if ( useecs )
mkeccl( ccltbl + cclmap[$1], ccllen[$1],
nextecm, ecgroup, csize, csize );
++rulelen;
$$ = mkstate( -$1 );
}
| PREVCCL
{
++rulelen;
$$ = mkstate( -$1 );
}
| '"' string '"'
{ $$ = $2; }
| '(' re ')'
{ $$ = $2; }
| CHAR
{
++rulelen;
if ( caseins && $1 >= 'A' && $1 <= 'Z' )
$1 = clower( $1 );
$$ = mkstate( $1 );
}
;
fullccl : '[' ccl ']'
{ $$ = $2; }
| '[' '^' ccl ']'
{
cclnegate( $3 );
$$ = $3;
}
;
ccl : ccl CHAR '-' CHAR
{
if ( caseins )
{
if ( $2 >= 'A' && $2 <= 'Z' )
$2 = clower( $2 );
if ( $4 >= 'A' && $4 <= 'Z' )
$4 = clower( $4 );
}
if ( $2 > $4 )
synerr( "negative range in character class" );
else
{
for ( i = $2; i <= $4; ++i )
ccladd( $1, i );
/* Keep track if this ccl is staying in
* alphabetical order.
*/
cclsorted = cclsorted && ($2 > lastchar);
lastchar = $4;
}
$$ = $1;
}
| ccl CHAR
{
if ( caseins && $2 >= 'A' && $2 <= 'Z' )
$2 = clower( $2 );
ccladd( $1, $2 );
cclsorted = cclsorted && ($2 > lastchar);
lastchar = $2;
$$ = $1;
}
| ccl ccl_expr
{
/* Too hard to properly maintain cclsorted. */
cclsorted = false;
$$ = $1;
}
|
{
cclsorted = true;
lastchar = 0;
currccl = $$ = cclinit();
}
;
ccl_expr: CCE_ALNUM { CCL_EXPR(isalnum) }
| CCE_ALPHA { CCL_EXPR(isalpha) }
| CCE_BLANK { CCL_EXPR(IS_BLANK) }
| CCE_CNTRL { CCL_EXPR(iscntrl) }
| CCE_DIGIT { CCL_EXPR(isdigit) }
| CCE_GRAPH { CCL_EXPR(isgraph) }
| CCE_LOWER { CCL_EXPR(islower) }
| CCE_PRINT { CCL_EXPR(isprint) }
| CCE_PUNCT { CCL_EXPR(ispunct) }
| CCE_SPACE { CCL_EXPR(isspace) }
| CCE_UPPER {
if ( caseins )
CCL_EXPR(islower)
else
CCL_EXPR(isupper)
}
| CCE_XDIGIT { CCL_EXPR(isxdigit) }
;
string : string CHAR
{
if ( caseins && $2 >= 'A' && $2 <= 'Z' )
$2 = clower( $2 );
++rulelen;
$$ = link_machines( $1, mkstate( $2 ) );
}
|
{ $$ = mkstate( SYM_EPSILON ); }
;
%%
/* build_eof_action - build the "<<EOF>>" action for the active start
* conditions
*/
void build_eof_action()
{
register int i;
char action_text[MAXLINE];
for ( i = 1; i <= scon_stk_ptr; ++i )
{
if ( sceof[scon_stk[i]] )
format_pinpoint_message(
"multiple <<EOF>> rules for start condition %s",
scname[scon_stk[i]] );
else
{
sceof[scon_stk[i]] = true;
sprintf( action_text, "case YY_STATE_EOF(%s):\n",
scname[scon_stk[i]] );
add_action( action_text );
}
}
line_directive_out( (FILE *) 0, 1 );
/* This isn't a normal rule after all - don't count it as
* such, so we don't have any holes in the rule numbering
* (which make generating "rule can never match" warnings
* more difficult.
*/
--num_rules;
++num_eof_rules;
}
/* format_synerr - write out formatted syntax error */
void format_synerr( msg, arg )
char msg[], arg[];
{
char errmsg[MAXLINE];
(void) sprintf( errmsg, msg, arg );
synerr( errmsg );
}
/* synerr - report a syntax error */
void synerr( str )
char str[];
{
syntaxerror = true;
pinpoint_message( str );
}
/* format_warn - write out formatted warning */
void format_warn( msg, arg )
char msg[], arg[];
{
char warn_msg[MAXLINE];
(void) sprintf( warn_msg, msg, arg );
warn( warn_msg );
}
/* warn - report a warning, unless -w was given */
void warn( str )
char str[];
{
line_warning( str, linenum );
}
/* format_pinpoint_message - write out a message formatted with one string,
* pinpointing its location
*/
void format_pinpoint_message( msg, arg )
char msg[], arg[];
{
char errmsg[MAXLINE];
(void) sprintf( errmsg, msg, arg );
pinpoint_message( errmsg );
}
/* pinpoint_message - write out a message, pinpointing its location */
void pinpoint_message( str )
char str[];
{
line_pinpoint( str, linenum );
}
/* line_warning - report a warning at a given line, unless -w was given */
void line_warning( str, line )
char str[];
int line;
{
char warning[MAXLINE];
if ( ! nowarn )
{
sprintf( warning, "warning, %s", str );
line_pinpoint( warning, line );
}
}
/* line_pinpoint - write out a message, pinpointing it at the given line */
void line_pinpoint( str, line )
char str[];
int line;
{
fprintf( stderr, "\"%s\", line %d: %s\n", infilename, line, str );
}
/* yyerror - eat up an error message from the parser;
* currently, messages are ignore
*/
void yyerror( msg )
char msg[];
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -