--- l2_spec_parse.y 2001/11/07 17:01:05 1.2
+++ l2_spec_parse.y 2001/11/08 09:28:35 1.3
@@ -53,161 +53,181 @@
#define YYERROR_VERBOSE
%}
- /* parser options */
+/* parser options */
%pure_parser
%locations
%defines
- /* the YYSTYPE: parser token value */
+/* the YYSTYPE: parser token value */
%union {
char *cpValue;
l2_channel_t *chChannel;
unsigned int nLevels;
}
- /* assign YYSTYPE elements to parser rules */
+/* assign YYSTYPE elements to parser rules */
%type <chChannel> stream
%type <chChannel> streams
%type <chChannel> channel
-%type <chChannel> channel_spec
-%type <nLevels> channel_mask
-%type <nLevels> channel_levels
+%type <chChannel> channel_cons
+%type <nLevels> channel_level
+%type <nLevels> channel_level_mask
- /* list of scanner tokens */
+/* list of scanner tokens */
%token <cpValue> T_ID
%token <cpValue> T_STRING
%token T_OP_ARROW
- /* operator association */
+/* operator association */
%right T_OP_ARROW
- /* grammar start rule */
+/* grammar start rule
+ (technically redundant but explicit to be sure) */
%start tree
%%
- /* channel tree */
-tree : stream
- { CTX->ch = $1; }
- ;
-
- /* stream of channels */
-stream : channel
- {
- $$ = $1;
- }
- | channel T_OP_ARROW stream
- {
- $$ = $1;
- if ((CTX->rv = l2_channel_link($1, L2_LINK_CHILD, $3, NULL)) != L2_OK) {
- l2_env_errorinfo(CTX->env, CTX->rv, "unable to link parent with child");
- YYERROR;
- }
- }
- | channel T_OP_ARROW '{' streams '}'
- {
- $$ = $1;
- if ((CTX->rv = l2_channel_link($1, L2_LINK_CHILD, $4, NULL)) != L2_OK) {
- l2_env_errorinfo(CTX->env, CTX->rv, "unable to link parent with child list");
- YYERROR;
- }
- }
- ;
-
- /* list of sibling streams */
-streams : stream
- { $$ = $1; }
- | stream ';' streams
- { $$ = $1; l2_channel_link($1, L2_LINK_SIBLING, $3, NULL); }
- ;
-
- /* single channel */
-channel : channel_mask '/' channel_mask ':' channel_spec
- { $$ = $5; l2_channel_levels($5, $1, $3); }
- | channel_mask ':' channel_spec
- { $$ = $3; l2_channel_levels($3, $1, L2_LEVEL_NONE); }
- | channel_spec
- { $$ = $1; }
- ;
-
- /* channel write or flush mask */
-channel_mask : T_ID
- {
- unsigned int levelmask;
- if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
- l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
- YYERROR;
- }
- $$ = L2_LEVEL_UPTO(levelmask);
- }
- | '(' channel_levels ')'
- {
- $$ = $2;
- }
- ;
-
- /* list of channels in a mask */
-channel_levels : T_ID
- {
- unsigned int levelmask;
- if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
- l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
- YYERROR;
- }
- $$ = levelmask;
- }
- | T_ID '|' channel_levels
- {
- unsigned int levelmask;
- if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
- l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
- YYERROR;
- }
- $$ = levelmask | $3;
- }
- ;
-
- /* specifcation of a single channel */
-channel_spec : T_ID
- {
- l2_channel_t *ch;
- if ((CTX->rv = l2_channel_create(&ch, CTX->env, $1)) != L2_OK) {
- l2_env_errorinfo(CTX->env, CTX->rv, "failed to create channel '%s'", $1);
- YYERROR;
- }
- $$ = ch;
- /* provide channel to channel_param rule below
- because it does not know where on the token stack
- our $$ is because it is a sub-rule of the recursive
- channel_param_list rule and hence cannot use
- "$<chChannel>-n". */
- CTX->chTmp = ch;
- }
- channel_params
- {
- $$ = $<chChannel>2; /* pass result */
- CTX->chTmp = NULL;
- }
- ;
-
- /* channel parameters */
-channel_params : /* empty */
- | '(' channel_param_list ')'
- ;
-
-channel_param_list : /* empty */
- | channel_param
- | channel_param ',' channel_param_list
- ;
+/* channel tree */
+tree
+ : stream {
+ CTX->ch = $1;
+ }
+ ;
+
+/* stream of channels */
+stream
+ : channel {
+ $$ = $1;
+ }
+ | channel T_OP_ARROW stream {
+ $$ = $1;
+ if ((CTX->rv = l2_channel_link($1, L2_LINK_CHILD, $3, NULL)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "unable to link parent with child");
+ YYERROR;
+ }
+ }
+ | channel T_OP_ARROW '{' streams '}' {
+ $$ = $1;
+ if ((CTX->rv = l2_channel_link($1, L2_LINK_CHILD, $4, NULL)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "unable to link parent with child list");
+ YYERROR;
+ }
+ }
+ ;
+
+/* list of sibling streams */
+streams
+ : stream {
+ $$ = $1;
+ }
+ | stream ';' streams {
+ $$ = $1;
+ if ((CTX->rv = l2_channel_link($1, L2_LINK_SIBLING, $3, NULL)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "unable to link childs together");
+ YYERROR;
+ }
+ }
+ ;
+
+/* channel */
+channel
+ : channel_level '/' channel_level ':' channel_cons {
+ $$ = $5;
+ if ((CTX->rv = l2_channel_levels($5, $1, $3)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "failed to set channel write and flush levels");
+ YYERROR;
+ }
+ }
+ | channel_level ':' channel_cons {
+ $$ = $3;
+ if ((CTX->rv = l2_channel_levels($3, $1, L2_LEVEL_NONE)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "failed to set channel write levels");
+ YYERROR;
+ }
+ }
+ | channel_cons {
+ $$ = $1;
+ }
+ ;
+
+/* channel level */
+channel_level
+ : T_ID {
+ unsigned int levelmask;
+ if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
+ YYERROR;
+ }
+ $$ = L2_LEVEL_UPTO(levelmask);
+ }
+ | '(' channel_level_mask ')' {
+ $$ = $2;
+ }
+ ;
+
+/* channel level mask */
+channel_level_mask
+ : T_ID {
+ unsigned int levelmask;
+ if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
+ YYERROR;
+ }
+ $$ = levelmask;
+ }
+ | T_ID '|' channel_level_mask {
+ unsigned int levelmask;
+ if ((CTX->rv = l2_util_s2l($1, strlen($1), ',', &levelmask)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "invalid level '%s'", $1);
+ YYERROR;
+ }
+ $$ = levelmask | $3;
+ }
+ ;
+
+/* channel constructor */
+channel_cons
+ : T_ID {
+ l2_channel_t *ch;
+ if ((CTX->rv = l2_channel_create(&ch, CTX->env, $1)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "failed to create channel '%s'", $1);
+ YYERROR;
+ }
+ $$ = ch;
+ /* provide channel to channel_param rule below because it does
+ not know where on the token stack our $$ is because it is a
+ sub-rule of the recursive channel_param_list rule and hence
+ cannot use "$<chChannel>-n". */
+ CTX->chTmp = ch;
+ }
+ channel_params {
+ $$ = $<chChannel>2; /* pass-through result */
+ CTX->chTmp = NULL;
+ }
+ ;
+
+/* channel parameters */
+channel_params
+ : /* empty */
+ | '(' channel_param_list ')'
+ ;
+
+/* channel parameter list */
+channel_param_list
+ : /* empty */
+ | channel_param
+ | channel_param ',' channel_param_list
+ ;
-channel_param : T_ID '=' T_STRING
- {
- if ((CTX->rv = l2_channel_configure(CTX->chTmp, "%s=\"%s\"", $1, $3)) != L2_OK) {
- l2_env_errorinfo(CTX->env, CTX->rv, "failed to configure channel with '%s=\"%s\"'", $1, $3);
- YYERROR;
- }
- }
- ;
+/* channel parameter */
+channel_param
+ : T_ID '=' T_STRING {
+ if ((CTX->rv = l2_channel_configure(CTX->chTmp, "%s=\"%s\"", $1, $3)) != L2_OK) {
+ l2_env_errorinfo(CTX->env, CTX->rv, "failed to configure channel with '%s=\"%s\"'", $1, $3);
+ YYERROR;
+ }
+ }
+ ;
%%
|