###### print binode cases
case Index:
- print_exec(b->left, -1, 0);
+ print_exec(b->left, -1, bracket);
printf("[");
- print_exec(b->right, -1, 0);
+ print_exec(b->right, -1, bracket);
printf("]");
break;
case Xfieldref:
{
struct fieldref *f = cast(fieldref, e);
- print_exec(f->left, -1, 0);
+ print_exec(f->left, -1, bracket);
printf(".%.*s", f->name.len, f->name.txt);
break;
}
###### Grammar
+ $LEFT if $$ifelse
+ ## expr precedence
+
$*exec
- Expression -> BoolExpr if Expression else Expression ${ {
+ Expression -> Expression if Expression else Expression $$ifelse ${ {
struct binode *b1 = new(binode);
struct binode *b2 = new(binode);
b1->op = CondExpr;
b2->right = $<5;
$0 = b1;
} }$
- | BoolExpr ${ $0 = $<1; }$
+ ## expression grammar
###### print binode cases
case CondExpr:
b2 = cast(binode, b->right);
- print_exec(b2->left, -1, 0);
+ if (bracket) printf("(");
+ print_exec(b2->left, -1, bracket);
printf(" if ");
- print_exec(b->left, -1, 0);
+ print_exec(b->left, -1, bracket);
printf(" else ");
- print_exec(b2->right, -1, 0);
+ print_exec(b2->right, -1, bracket);
+ if (bracket) printf(")");
break;
###### propagate binode cases
OrElse,
Not,
-###### Grammar
+###### expr precedence
+ $LEFT or
+ $LEFT and
+ $LEFT not
- $*exec
- BoolExpr -> BoolExpr or BTerm ${ {
+###### expression grammar
+ | Expression or Expression ${ {
struct binode *b = new(binode);
b->op = Or;
b->left = $<1;
b->right = $<3;
$0 = b;
} }$
- | BoolExpr or else BTerm ${ {
+ | Expression or else Expression ${ {
struct binode *b = new(binode);
b->op = OrElse;
b->left = $<1;
b->right = $<4;
$0 = b;
} }$
- | BTerm ${ $0 = $<1; }$
- BTerm -> BTerm and BFact ${ {
+ | Expression and Expression ${ {
struct binode *b = new(binode);
b->op = And;
b->left = $<1;
b->right = $<3;
$0 = b;
} }$
- | BTerm and then BFact ${ {
+ | Expression and then Expression ${ {
struct binode *b = new(binode);
b->op = AndThen;
b->left = $<1;
b->right = $<4;
$0 = b;
} }$
- | BFact ${ $0 = $<1; }$
- BFact -> not BFact ${ {
+ | not Expression ${ {
struct binode *b = new(binode);
b->op = Not;
b->right = $<2;
$0 = b;
} }$
- ## other BFact
###### print binode cases
case And:
- print_exec(b->left, -1, 0);
+ if (bracket) printf("(");
+ print_exec(b->left, -1, bracket);
printf(" and ");
- print_exec(b->right, -1, 0);
+ print_exec(b->right, -1, bracket);
+ if (bracket) printf(")");
break;
case AndThen:
- print_exec(b->left, -1, 0);
+ if (bracket) printf("(");
+ print_exec(b->left, -1, bracket);
printf(" and then ");
- print_exec(b->right, -1, 0);
+ print_exec(b->right, -1, bracket);
+ if (bracket) printf(")");
break;
case Or:
- print_exec(b->left, -1, 0);
+ if (bracket) printf("(");
+ print_exec(b->left, -1, bracket);
printf(" or ");
- print_exec(b->right, -1, 0);
+ print_exec(b->right, -1, bracket);
+ if (bracket) printf(")");
break;
case OrElse:
- print_exec(b->left, -1, 0);
+ if (bracket) printf("(");
+ print_exec(b->left, -1, bracket);
printf(" or else ");
- print_exec(b->right, -1, 0);
+ print_exec(b->right, -1, bracket);
+ if (bracket) printf(")");
break;
case Not:
+ if (bracket) printf("(");
printf("not ");
- print_exec(b->right, -1, 0);
+ print_exec(b->right, -1, bracket);
+ if (bracket) printf(")");
break;
###### propagate binode cases
Eql,
NEql,
-###### other BFact
- | Expr CMPop Expr ${ {
+###### expr precedence
+ $LEFT < > <= >= == != CMPop
+
+###### expression grammar
+ | Expression CMPop Expression ${ {
struct binode *b = new(binode);
b->op = $2.op;
b->left = $<1;
b->right = $<3;
$0 = b;
} }$
- | Expr ${ $0 = $<1; }$
###### Grammar
case GtrEq:
case Eql:
case NEql:
- print_exec(b->left, -1, 0);
+ if (bracket) printf("(");
+ print_exec(b->left, -1, bracket);
switch(b->op) {
case Less: printf(" < "); break;
case LessEq: printf(" <= "); break;
case NEql: printf(" != "); break;
default: abort(); // NOTEST
}
- print_exec(b->right, -1, 0);
+ print_exec(b->right, -1, bracket);
+ if (bracket) printf(")");
break;
###### propagate binode cases
Absolute, Negate,
Bracket,
-###### Grammar
+###### expr precedence
+ $LEFT + - Eop
+ $LEFT * / % ++ Top
+ $LEFT Uop
- $*exec
- Expr -> Expr Eop Term ${ {
+###### expression grammar
+ | Expression Eop Expression ${ {
struct binode *b = new(binode);
b->op = $2.op;
b->left = $<1;
b->right = $<3;
$0 = b;
} }$
- | Term ${ $0 = $<1; }$
- Term -> Term Top Factor ${ {
+ | Expression Top Expression ${ {
struct binode *b = new(binode);
b->op = $2.op;
b->left = $<1;
b->right = $<3;
$0 = b;
} }$
- | Factor ${ $0 = $<1; }$
- Factor -> ( Expression ) ${ {
+ | ( Expression ) ${ {
struct binode *b = new_pos(binode, $1);
b->op = Bracket;
b->right = $<2;
$0 = b;
} }$
- | Uop Factor ${ {
+ | Uop Expression ${ {
struct binode *b = new(binode);
b->op = $1.op;
b->right = $<2;
case Divide:
case Concat:
case Rem:
- print_exec(b->left, indent, 0);
+ if (bracket) printf("(");
+ print_exec(b->left, indent, bracket);
switch(b->op) {
case Plus: fputs(" + ", stdout); break;
case Minus: fputs(" - ", stdout); break;
case Concat: fputs(" ++ ", stdout); break;
default: abort(); // NOTEST
} // NOTEST
- print_exec(b->right, indent, 0);
+ print_exec(b->right, indent, bracket);
+ if (bracket) printf(")");
break;
case Absolute:
+ if (bracket) printf("(");
printf("+");
- print_exec(b->right, indent, 0);
+ print_exec(b->right, indent, bracket);
+ if (bracket) printf(")");
break;
case Negate:
+ if (bracket) printf("(");
printf("-");
- print_exec(b->right, indent, 0);
+ print_exec(b->right, indent, bracket);
+ if (bracket) printf(")");
break;
case Bracket:
printf("(");
- print_exec(b->right, indent, 0);
+ print_exec(b->right, indent, bracket);
printf(")");
break;
###### Grammar
- $void
- Newlines -> NEWLINE
- | Newlines NEWLINE
-
$*binode
Block -> Open Statementlist Close ${ $0 = $<2; }$
| Open SimpleStatements } ${ $0 = reorder_bilist($<2); }$
- | : SimpleStatements ${ $0 = reorder_bilist($<2); }$
- | : Statementlist ${ $0 = $<2; }$
+ | : SimpleStatements $$NEWLINE ${ $0 = reorder_bilist($<2); }$
+ | : Statementlist $$NEWLINE ${ $0 = $<2; }$
Statementlist -> ComplexStatements ${ $0 = reorder_bilist($<1); }$
+ | NEWLINE Statementlist ${ $0 = $<2; }$
ComplexStatements -> ComplexStatements ComplexStatement ${
if ($2 == NULL) {
}$
$*exec
- ComplexStatement -> SimpleStatements NEWLINE ${
+ ComplexStatement -> SimpleStatementLine ${
$0 = reorder_bilist($<1);
}$
- | Newlines ${ $0 = NULL; }$
+ | ComplexStatement NEWLINE ${ $0 = $<1; }$
## ComplexStatement Grammar
$*binode
}$
| SimpleStatements ; ${ $0 = $<1; }$
+ SimpleStatementLine -> SimpleStatements NEWLINE ${ $0 = $<1; }$
+ | SimpleStatementLine NEWLINE ${ $0 = $<1; }$
+
SimpleStatement -> pass ${ $0 = NULL; }$
| ERROR ${ tok_err(c, "Syntax error in statement", &$1); }$
## SimpleStatement Grammar
if (b->left == NULL)
printf("pass");
else
- print_exec(b->left, indent, 0);
+ print_exec(b->left, indent, bracket);
if (b->right) {
printf("; ");
- print_exec(b->right, indent, 0);
+ print_exec(b->right, indent, bracket);
}
} else {
// block, one per line
while (b) {
if (b->left) {
printf(" ");
- print_exec(b->left, -1, 0);
+ print_exec(b->left, -1, bracket);
if (b->right)
printf(",");
}
case Assign:
do_indent(indent, "");
- print_exec(b->left, indent, 0);
+ print_exec(b->left, indent, bracket);
printf(" = ");
- print_exec(b->right, indent, 0);
+ print_exec(b->right, indent, bracket);
if (indent >= 0)
printf("\n");
break;
{
struct variable *v = cast(var, b->left)->var;
do_indent(indent, "");
- print_exec(b->left, indent, 0);
+ print_exec(b->left, indent, bracket);
if (cast(var, b->left)->var->constant) {
if (v->where_decl == v->where_set) {
printf("::");
}
if (b->right) {
printf("= ");
- print_exec(b->right, indent, 0);
+ print_exec(b->right, indent, bracket);
}
if (indent >= 0)
printf("\n");
case Use:
do_indent(indent, "use ");
- print_exec(b->right, -1, 0);
+ print_exec(b->right, -1, bracket);
if (indent >= 0)
printf("\n");
break;
$*cond_statement
// both ForThen and Whilepart open scopes, and CondSuffix only
// closes one - so in the first branch here we have another to close.
- CondStatement -> forPart ThenPart WhilePart CondSuffix ${
+ CondStatement -> ForPart ThenPart WhilePart CondSuffix ${
$0 = $<4;
$0->forpart = $<1;
$0->thenpart = $<2;
$0->dopart = $3.dopart; $3.dopart = NULL;
var_block_close(c, CloseSequential);
}$
- | forPart WhilePart CondSuffix ${
+ | ForPart WhilePart CondSuffix ${
$0 = $<3;
$0->forpart = $<1;
$0->thenpart = NULL;
$0->dopart = $2.dopart; $2.dopart = NULL;
var_block_close(c, CloseSequential);
}$
- | whilePart CondSuffix ${
+ | WhilePart CondSuffix ${
$0 = $<2;
$0->condpart = $1.condpart; $1.condpart = NULL;
$0->dopart = $1.dopart; $1.dopart = NULL;
}$
- | switchPart CondSuffix ${
- $0 = $<2;
+ | SwitchPart CasePart CondSuffix ${
+ $0 = $<3;
$0->condpart = $<1;
+ $2->next = $0->casepart;
+ $0->casepart = $<2;
}$
- | ifPart IfSuffix ${
+ | IfPart IfSuffix ${
$0 = $<2;
$0->condpart = $1.condpart; $1.condpart = NULL;
$0->thenpart = $1.thenpart; $1.thenpart = NULL;
$0->casepart = $<1;
}$
- $void
- Case -> case
- | NEWLINE Case
$*casepart
- CasePart -> Case Expression OpenScope Block ${
+ CasePart -> case Expression OpenScope Block ${
$0 = calloc(1,sizeof(struct casepart));
$0->value = $<2;
$0->action = $<4;
var_block_close(c, CloseParallel);
}$
+ | CasePart NEWLINE ${ $0 = $<1; }$
$*cond_statement
IfSuffix -> ${ $0 = new(cond_statement); }$
- | NEWLINE IfSuffix ${ $0 = $<2; }$
+ | IfSuffix NEWLINE ${ $0 = $<1; }$
| else OpenScope Block ${
$0 = new(cond_statement);
$0->elsepart = $<3;
var_block_close(c, CloseElse);
}$
- $void
- Then -> then
- | NEWLINE Then
- While -> while
- | NEWLINE While
- Do -> do
- | NEWLINE Do
$*exec
// These scopes are closed in CondSuffix
- forPart -> for OpenScope SimpleStatements ${
+ ForPart -> for OpenScope SimpleStatements ${
$0 = reorder_bilist($<3);
}$
| for OpenScope Block ${
$0 = $<3;
}$
+ | ForPart NEWLINE ${ $0 = $<1; }$
- ThenPart -> Then OpenScope SimpleStatements ${
+ ThenPart -> then OpenScope SimpleStatements ${
$0 = reorder_bilist($<3);
var_block_close(c, CloseSequential);
}$
- | Then OpenScope Block ${
+ | then OpenScope Block ${
$0 = $<3;
var_block_close(c, CloseSequential);
}$
+ | ThenPart NEWLINE ${ $0 = $<1; }$
// This scope is closed in CondSuffix
- WhileHead -> While OpenScope Block ${
- $0 = $<3;
- }$
- whileHead -> while OpenScope Block ${
- $0 = $<3;
- }$
+ WhileHead -> while OpenScope Block ${ $0 = $<3; }$
+ | WhileHead NEWLINE ${ $0 = $<1; }$
$cond_statement
// This scope is closed in CondSuffix
- whilePart -> while OpenScope Expression Block ${
- $0.type = Xcond_statement;
- $0.condpart = $<3;
- $0.dopart = $<4;
- }$
- | whileHead Do Block ${
- $0.type = Xcond_statement;
- $0.condpart = $<1;
- $0.dopart = $<3;
- }$
- WhilePart -> While OpenScope Expression Block ${
+ WhilePart -> while OpenScope Expression Block ${
$0.type = Xcond_statement;
$0.condpart = $<3;
$0.dopart = $<4;
}$
- | WhileHead Do Block ${
+ | WhileHead do Block ${
$0.type = Xcond_statement;
$0.condpart = $<1;
$0.dopart = $<3;
}$
+ | WhilePart NEWLINE ${ $0 = $<1; }$
- ifPart -> if OpenScope Expression OpenScope Block ${
+ IfPart -> if OpenScope Expression OpenScope Block ${
$0.type = Xcond_statement;
$0.condpart = $<3;
$0.thenpart = $<5;
var_block_close(c, CloseParallel);
}$
- | if OpenScope Block Then OpenScope Block ${
+ | if OpenScope Block then OpenScope Block ${
$0.type = Xcond_statement;
$0.condpart = $<3;
$0.thenpart = $<6;
var_block_close(c, CloseParallel);
}$
+ | IfPart NEWLINE ${ $0 = $<1; }$
$*exec
// This scope is closed in CondSuffix
- switchPart -> switch OpenScope Expression ${
+ SwitchPart -> switch OpenScope Expression ${
$0 = $<3;
}$
| switch OpenScope Block ${
$0 = $<3;
}$
+ | SwitchPart NEWLINE ${ $0 = $<1; }$
###### print exec cases
var_block_close(c, CloseSequential);
if (c->scope_stack && !c->parse_error) abort();
}$
- | ERROR ${
- tok_err(c,
- "error: unhandled parse error", &$1);
- }$
Varlist -> Varlist ArgDecl ${
$0 = new(binode);