Open mingodad opened 3 years ago
hi @mingodad - it's great that you figured out how to do this but it's posted here as a GitHub issue which normally means there's some further step that is needed?
Is this informational or is there some next step you are asking for help with?
It's informational, possible further steps would be to add missing tokens definitions for completeness.
INTLITERAL
REALLITERAL
IMAGLITERAL
CSTRINGLITERAL
COMMENTS
@mingodad - alright. If it's informational then I think it'd make sense to close the issue (to indicate it's not something that needs further work from the project). It will remain available to find when searching issues etc. Thanks.
I think that adding it to the documentation could help new users have a global view of the language.
Are you asking to have the graphical grammar / railroad diagram added to the documentation, or are you asking that the instructions to create it be added?
If you are hoping that the graphical grammar be added to the documentation -- I'm not sure how big the graphical grammar representation is but we'd need it to be some kind of image to include it in the documentation. Another concern would be updating these images when the grammar changes (supposing that it is a manual process). Would you be able to produce and share an image / images in order to facilitate discussion? You could add it to a github gist for now, for example.
On the https://www.bottlecaps.de/rr/ui there is a button to export it as self contained xhtml
in fact what we are seeing there is the generated xhtml
in a frame.
We can have the graphical grammar with basically no manual work if we left the Tokens
definition out.
There is ways to automate with sed
scripts (or perl, python, ...).
But Normally the grammar doesn't change drastically frequently.
Ah, I've tried pasting it in that website and it looks like a reasonable improvement over just the grammar listings. I'm curious what others think though. I'll paste a screen shot to enable discussion.
I agree that this looks like it could be an attractive addition to (or possible replacement for?) our current syntax summary at https://chapel-lang.org/docs/language/spec/syntax.html. I think we'd need this to be auto-generated on each build of the spec/docs, though, not something that requires a developer to be in the loop for (or it'd definitely fall out of date quickly).
Looks like the railroad diagram generator is open source, written in Java, and Apache 2 licensed.
I think the next step on this issue would be to create some scripts to generate the railroad diagrams and integrate these into our rendered language specification. Ideally make docs
would do everything needed here (including possibly downloading the dependency).
Also I did a script to replace positional references by named references see bellow applying it to chaperl.ypp
:
program:
toplevel_stmt_ls { yyblock = $program; }
;
toplevel_stmt_ls:
{ $toplevel_stmt_ls = new BlockStmt(); resetTempID(); }
| toplevel_stmt_ls[rhs_1] toplevel_stmt { $rhs_1->appendChapelStmt($toplevel_stmt); context->generatedStmt = $rhs_1; resetTempID(); }
;
toplevel_stmt:
stmt
| pragma_ls stmt { $toplevel_stmt = buildPragmaStmt( $pragma_ls, $stmt ); }
;
pragma_ls:
TPRAGMA STRINGLITERAL { $pragma_ls = new Vec<const char*>(); $pragma_ls->add(astr($STRINGLITERAL)); }
| pragma_ls[rhs_1] TPRAGMA STRINGLITERAL { $rhs_1->add(astr($STRINGLITERAL)); }
;
stmt:
module_decl_stmt
| include_module_stmt
| block_stmt
| use_stmt
| import_stmt
| require_stmt
| class_level_stmt
| assignment_stmt
| extern_block_stmt
| if_stmt
| implements_stmt
| interface_stmt
| loop_stmt
| select_stmt
| defer_stmt
| try_stmt
| throw_stmt
| return_stmt
| stmt_level_expr TSEMI { $stmt = buildChapelStmt($stmt_level_expr); }
| TATOMIC stmt[rhs_1] { $$ /* stmt */ = buildAtomicStmt($rhs_1); }
| TBEGIN opt_task_intent_ls stmt[rhs_1] { $$ /* stmt */ = buildBeginStmt($opt_task_intent_ls, $rhs_1); }
| TBREAK opt_label_ident TSEMI { $stmt = buildGotoStmt(GOTO_BREAK, $opt_label_ident); }
| TCOBEGIN opt_task_intent_ls block_stmt { $stmt = buildCobeginStmt($opt_task_intent_ls, $block_stmt); }
| TCONTINUE opt_label_ident TSEMI { $stmt = buildGotoStmt(GOTO_CONTINUE, $opt_label_ident); }
| TDELETE simple_expr_ls TSEMI { $stmt = buildDeleteStmt($simple_expr_ls); }
| TLABEL ident_def stmt[rhs_1] { $$ /* stmt */ = buildLabelStmt($ident_def, $rhs_1); }
| TLOCAL expr do_stmt { $stmt = buildLocalStmt($expr, $do_stmt); }
| TLOCAL do_stmt { $stmt = buildLocalStmt($do_stmt); }
| TON expr do_stmt { $stmt = buildOnStmt($expr, $do_stmt); }
| TSERIAL expr do_stmt { $stmt = buildSerialStmt($expr, $do_stmt); }
| TSERIAL do_stmt { $stmt = buildSerialStmt(new SymExpr(gTrue), $do_stmt); }
| TSYNC stmt[rhs_1] { $$ /* stmt */ = buildSyncStmt($rhs_1); }
| TYIELD expr TSEMI { $stmt = buildPrimitiveStmt(PRIM_YIELD, $expr); }
| error TSEMI { $stmt = buildErrorStandin(); }
;
module_decl_start:
access_control opt_prototype TMODULE ident_def {
$module_decl_start = buildModule($ident_def, currentModuleType, NULL, yyfilename, $access_control, $opt_prototype, @access_control.comment);
// store previous module name in order to restore it once we're
// done with this module in module_decl_stmt below. Ultimately,
// we will need to store a stack of module names in order to
// support full module path resolution of -s config flags.
@$.prevModule = currentModuleName;
currentModuleName = $ident_def;
}
;
module_decl_stmt:
module_decl_start TLCBR TRCBR { $module_decl_start->block = new BlockStmt();
$module_decl_stmt = buildChapelStmt(new DefExpr($module_decl_start));
currentModuleName = @module_decl_start.prevModule; // restore previous module name
}
| module_decl_start TLCBR stmt_ls TRCBR { $module_decl_start->block = $stmt_ls;
$module_decl_stmt = buildChapelStmt(new DefExpr($module_decl_start));
currentModuleName = @module_decl_start.prevModule; // restore previous module name
}
| module_decl_start TLCBR error TRCBR { $module_decl_start->block = buildErrorStandin();
$module_decl_stmt = buildChapelStmt(new DefExpr($module_decl_start));
currentModuleName = @module_decl_start.prevModule; // restore previous module name
}
;
access_control:
{ $access_control = false; @$.comment = context->latestComment; context->latestComment = NULL; }
// public
| TPUBLIC { $access_control = false; @$.comment = context->latestComment; context->latestComment = NULL; }
// also public
| TPRIVATE { $access_control = true; @$.comment = context->latestComment; context->latestComment = NULL; } // private
;
opt_prototype:
{ $opt_prototype = false; }
| TPROTOTYPE { $opt_prototype = true; }
;
include_access_control:
{ $include_access_control = false; }
| TPUBLIC { $include_access_control = false; }
| TPRIVATE { $include_access_control = true; }
;
include_module_stmt:
TINCLUDE {
@TINCLUDE.comment = context->latestComment;
context->latestComment = NULL;
}
include_access_control opt_prototype TMODULE ident_def TSEMI {
$include_module_stmt = buildIncludeModule($ident_def, $include_access_control, $opt_prototype, @TINCLUDE.comment);
}
;
block_stmt:
TLCBR TRCBR { $block_stmt = new BlockStmt(); }
| TLCBR stmt_ls TRCBR { $block_stmt = $stmt_ls; }
| TLCBR error TRCBR { $block_stmt = buildErrorStandin(); }
;
stmt_ls:
toplevel_stmt { $stmt_ls = new BlockStmt(); $stmt_ls->appendChapelStmt($toplevel_stmt); }
| stmt_ls[rhs_1] toplevel_stmt { $rhs_1->appendChapelStmt($toplevel_stmt); }
;
renames_ls:
expr { $renames_ls = new std::vector<PotentialRename*>();
PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::SINGLE;
cur->elem = $expr;
$renames_ls->push_back(cur); }
| expr TAS expr { $renames_ls = new std::vector<PotentialRename*>();
PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::DOUBLE;
cur->renamed = new std::pair<Expr*, Expr*>($1 /* expr_1 */, $3 /* expr_3 */);
$renames_ls->push_back(cur); }
| renames_ls[rhs_1] TCOMMA expr { PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::SINGLE;
cur->elem = $expr;
$rhs_1->push_back(cur); }
| renames_ls[rhs_1] TCOMMA expr TAS expr { PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::DOUBLE;
cur->renamed = new std::pair<Expr*, Expr*>($3 /* expr_3 */, $5 /* expr_5 */);
$rhs_1->push_back(cur); }
;
use_renames_ls:
expr { $use_renames_ls = new std::vector<PotentialRename*>();
PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::SINGLE;
cur->elem = $expr;
$use_renames_ls->push_back(cur); }
| expr TAS expr { $use_renames_ls = new std::vector<PotentialRename*>();
PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::DOUBLE;
cur->renamed = new std::pair<Expr*, Expr*>($1 /* expr_1 */, $3 /* expr_3 */);
$use_renames_ls->push_back(cur); }
| expr TAS TUNDERSCORE { $use_renames_ls = new std::vector<PotentialRename*>();
PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::DOUBLE;
cur->renamed = new std::pair<Expr*, Expr*>($expr, new UnresolvedSymExpr("_"));
$use_renames_ls->push_back(cur); }
| use_renames_ls[rhs_1] TCOMMA expr { PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::SINGLE;
cur->elem = $expr;
$rhs_1->push_back(cur); }
| use_renames_ls[rhs_1] TCOMMA expr TAS expr { PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::DOUBLE;
cur->renamed = new std::pair<Expr*, Expr*>($3 /* expr_3 */, $5 /* expr_5 */);
$rhs_1->push_back(cur); }
| use_renames_ls[rhs_1] TCOMMA expr TAS TUNDERSCORE { PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::DOUBLE;
cur->renamed = new std::pair<Expr*, Expr*>($expr, new UnresolvedSymExpr("_"));
$rhs_1->push_back(cur); }
;
opt_only_ls:
/* nothing */ { $opt_only_ls = new std::vector<PotentialRename*>();
PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::SINGLE;
cur->elem = new UnresolvedSymExpr("");
$opt_only_ls->push_back(cur); }
| renames_ls
;
except_ls:
TSTAR { $except_ls = new std::vector<PotentialRename*>();
PotentialRename* cur = new PotentialRename();
cur->tag = PotentialRename::SINGLE;
cur->elem = new UnresolvedSymExpr("");
$except_ls->push_back(cur); }
| renames_ls
;
use_access_control:
{ $use_access_control = true; }
// private
| TPUBLIC { $use_access_control = false; }
// public
| TPRIVATE { $use_access_control = true; } // private
;
use_stmt:
use_access_control TUSE use_renames_ls TSEMI { $use_stmt = buildUseStmt($use_renames_ls, $use_access_control); }
| use_access_control TUSE expr TEXCEPT except_ls TSEMI { $use_stmt = buildUseStmt($expr, "", $except_ls, true, $use_access_control); }
| use_access_control TUSE expr TAS expr TEXCEPT except_ls TSEMI { $use_stmt = buildUseStmt($3 /* expr_3 */, $5 /* expr_5 */, $except_ls, true, $use_access_control); }
| use_access_control TUSE expr TAS TUNDERSCORE TEXCEPT except_ls TSEMI { $use_stmt = buildUseStmt($expr, new UnresolvedSymExpr("_"), $except_ls, true, $use_access_control); }
| use_access_control TUSE expr TONLY opt_only_ls TSEMI { $use_stmt = buildUseStmt($expr, "", $opt_only_ls, false, $use_access_control); }
| use_access_control TUSE expr TAS expr TONLY opt_only_ls TSEMI { $use_stmt = buildUseStmt($3 /* expr_3 */, $5 /* expr_5 */, $opt_only_ls, false, $use_access_control); }
| use_access_control TUSE expr TAS TUNDERSCORE TONLY opt_only_ls TSEMI { $use_stmt = buildUseStmt($expr, new UnresolvedSymExpr("_"), $opt_only_ls, false, $use_access_control); }
;
import_stmt:
use_access_control TIMPORT import_ls TSEMI { $import_stmt = $import_ls;
setImportPrivacy($import_stmt, $use_access_control);}
;
import_expr:
expr { $import_expr = buildImportStmt($expr); }
| expr TAS ident_use { $import_expr = buildImportStmt($expr, $ident_use); }
| expr TDOT TLCBR renames_ls TRCBR { $import_expr = buildImportStmt($expr, $renames_ls); }
;
import_ls:
import_expr { $import_ls = buildChapelStmt($import_expr); }
| import_ls[rhs_1] TCOMMA import_expr { $$ /* import_ls */ = $rhs_1; $$ /* import_ls */->insertAtTail($import_expr); }
;
require_stmt:
TREQUIRE expr_ls TSEMI { $require_stmt = buildRequireStmt($expr_ls); }
;
assignment_stmt:
lhs_expr assignop_ident opt_try_expr TSEMI { $assignment_stmt = buildAssignment($lhs_expr, $opt_try_expr, $assignop_ident); }
| lhs_expr TSWAP opt_try_expr TSEMI { $assignment_stmt = buildAssignment($lhs_expr, $opt_try_expr, "<=>"); }
| lhs_expr TASSIGNREDUCE opt_try_expr TSEMI { $assignment_stmt = buildAssignment($lhs_expr, $opt_try_expr, PRIM_REDUCE_ASSIGN); }
| lhs_expr TASSIGNLAND opt_try_expr TSEMI { $assignment_stmt = buildLAndAssignment($lhs_expr, $opt_try_expr); }
| lhs_expr TASSIGNLOR opt_try_expr TSEMI { $assignment_stmt = buildLOrAssignment($lhs_expr, $opt_try_expr); }
| lhs_expr TASSIGN TNOINIT TSEMI { $assignment_stmt = buildAssignment($lhs_expr, new SymExpr(gNoInit), "="); }
;
opt_label_ident:
{ $opt_label_ident = NULL; }
| TIDENT { $opt_label_ident = $TIDENT; }
;
ident_fn_def:
TIDENT { $ident_fn_def = $TIDENT; }
| TNONE { $ident_fn_def = "none"; redefiningReservedWordError($ident_fn_def); }
| TTHIS { $ident_fn_def = "this"; }
| TFALSE { $ident_fn_def = "false"; redefiningReservedWordError($ident_fn_def); }
| TTRUE { $ident_fn_def = "true"; redefiningReservedWordError($ident_fn_def); }
| internal_type_ident_def { $ident_fn_def = $internal_type_ident_def; redefiningReservedTypeError($internal_type_ident_def); }
;
ident_def:
TIDENT { $ident_def = $TIDENT; }
| TNONE { $ident_def = "none"; redefiningReservedWordError($ident_def); }
| TTHIS { $ident_def = "this"; redefiningReservedWordError($ident_def); }
| TFALSE { $ident_def = "false"; redefiningReservedWordError($ident_def); }
| TTRUE { $ident_def = "true"; redefiningReservedWordError($ident_def); }
| internal_type_ident_def { $ident_def = $internal_type_ident_def; redefiningReservedTypeError($internal_type_ident_def); }
;
ident_use:
TIDENT { $ident_use = $TIDENT; }
| TTHIS { $ident_use = "this"; }
;
internal_type_ident_def:
/* These reserved words should generate an error if an attempt
is made to redefine them. The name returned from this nonterminal
will be used in the error message.
Uses of these types are parsed differently.
See scalar_type and reserved_type_ident_use.
*/
TBOOL { $internal_type_ident_def = "bool"; }
| TINT { $internal_type_ident_def = "int"; }
| TUINT { $internal_type_ident_def = "uint"; }
| TREAL { $internal_type_ident_def = "real"; }
| TIMAG { $internal_type_ident_def = "imag"; }
| TCOMPLEX { $internal_type_ident_def = "complex"; }
| TBYTES { $internal_type_ident_def = "bytes"; }
| TSTRING { $internal_type_ident_def = "string"; }
| TSYNC { $internal_type_ident_def = "sync"; }
| TSINGLE { $internal_type_ident_def = "single"; }
| TOWNED { $internal_type_ident_def = "owned"; }
| TSHARED { $internal_type_ident_def = "shared"; }
| TBORROWED { $internal_type_ident_def = "borrowed"; }
| TUNMANAGED { $internal_type_ident_def = "unmanaged"; }
| TDOMAIN { $internal_type_ident_def = "domain"; }
| TINDEX { $internal_type_ident_def = "index"; }
| TLOCALE { $internal_type_ident_def = "locale"; }
| TNOTHING { $internal_type_ident_def = "nothing"; }
| TVOID { $internal_type_ident_def = "void"; }
;
scalar_type:
TBOOL { $scalar_type = new SymExpr(dtBools[BOOL_SIZE_DEFAULT]->symbol); }
| TENUM { $scalar_type = new SymExpr(dtAnyEnumerated->symbol); }
| TINT { $scalar_type = new SymExpr(dtInt[INT_SIZE_DEFAULT]->symbol); }
| TUINT { $scalar_type = new SymExpr(dtUInt[INT_SIZE_DEFAULT]->symbol); }
| TREAL { $scalar_type = new SymExpr(dtReal[FLOAT_SIZE_DEFAULT]->symbol); }
| TIMAG { $scalar_type = new SymExpr(dtImag[FLOAT_SIZE_DEFAULT]->symbol); }
| TCOMPLEX { $scalar_type = new SymExpr(dtComplex[COMPLEX_SIZE_DEFAULT]->symbol); }
| TBYTES { $scalar_type = new SymExpr(dtBytes->symbol); }
| TSTRING { $scalar_type = new SymExpr(dtString->symbol); }
| TLOCALE { $scalar_type = new SymExpr(dtLocale->symbol); }
| TNOTHING { $scalar_type = new SymExpr(dtNothing->symbol); }
| TVOID { $scalar_type = new SymExpr(dtVoid->symbol); }
;
reserved_type_ident_use:
/* These reserved words can also be used as types but in fewer
places in the parser. Additionally their type versions have
different names. */
TSYNC { $reserved_type_ident_use = "_syncvar"; }
| TSINGLE { $reserved_type_ident_use = "_singlevar"; }
| TDOMAIN { $reserved_type_ident_use = "_domain"; }
| TINDEX { $reserved_type_ident_use = "_index"; }
;
do_stmt:
TDO stmt { $do_stmt = $stmt; }
| block_stmt { $do_stmt = $block_stmt; }
;
return_stmt:
TRETURN TSEMI { $return_stmt = buildPrimitiveStmt(PRIM_RETURN); }
| TRETURN opt_try_expr TSEMI { $return_stmt = buildPrimitiveStmt(PRIM_RETURN, $opt_try_expr); }
;
class_level_stmt:
TSEMI { $class_level_stmt = buildChapelStmt(new BlockStmt()); }
| private_decl
| TPUBLIC private_decl { $class_level_stmt = $private_decl; }
/* the following rule saves the current state of `parsingPrivate`,
then sets it to true when parsing the `private_decl` rule; it then
restores the original value before completing. Note that this is
not sufficient to reason about nestings of public and private
declarations, but that the current use of `parsingPrivate` (to
distinguish private configs) does not require that. For such
cases, we'd need to do similar save/set-to-false/restore actions in
the public rules above, but doing this in the most straightforward
way results in conflicts. */
| TPRIVATE { $<b>$ = parsingPrivate; parsingPrivate=true;}
private_decl { parsingPrivate=$<b>2; applyPrivateToBlock($private_decl); $class_level_stmt = $private_decl; }
;
private_decl:
fn_decl_stmt
| var_decl_stmt
| enum_decl_stmt
| type_alias_decl_stmt
| class_decl_stmt
| forwarding_stmt
| extern_export_decl_stmt
;
forwarding_stmt:
TFORWARDING expr TSEMI { $forwarding_stmt = buildForwardingStmt($expr); }
| TFORWARDING expr TEXCEPT except_ls TSEMI { $forwarding_stmt = buildForwardingStmt($expr, $except_ls, true); }
| TFORWARDING expr TONLY opt_only_ls TSEMI { $forwarding_stmt = buildForwardingStmt($expr, $opt_only_ls, false); }
| TFORWARDING var_decl_stmt { $forwarding_stmt = buildForwardingDeclStmt($var_decl_stmt); }
;
extern_export_decl_stmt:
TEXTERN TRECORD {
@TRECORD.comment = context->latestComment;
context->latestComment = NULL;
}
ident_def opt_inherit TLCBR class_level_stmt_ls TRCBR {
$extern_export_decl_stmt = buildChapelStmt(buildClassDefExpr($ident_def,
NULL,
AGGREGATE_RECORD,
$opt_inherit,
$class_level_stmt_ls,
FLAG_EXTERN,
@TRECORD.comment));
}
| TEXTERN STRINGLITERAL TRECORD {
@TRECORD.comment = context->latestComment;
context->latestComment = NULL;
}
ident_def opt_inherit TLCBR class_level_stmt_ls TRCBR {
$extern_export_decl_stmt = buildChapelStmt(buildClassDefExpr($ident_def,
$STRINGLITERAL,
AGGREGATE_RECORD,
$opt_inherit,
$class_level_stmt_ls,
FLAG_EXTERN,
@TRECORD.comment));
}
| TEXPORT TRECORD {
@TRECORD.comment = context->latestComment;
context->latestComment = NULL;
}
ident_def opt_inherit TLCBR class_level_stmt_ls TRCBR {
$extern_export_decl_stmt = buildChapelStmt(buildClassDefExpr($ident_def,
NULL,
AGGREGATE_RECORD,
$opt_inherit,
$class_level_stmt_ls,
FLAG_EXPORT,
@TRECORD.comment));
}
| TEXPORT STRINGLITERAL TRECORD {
@TRECORD.comment = context->latestComment;
context->latestComment = NULL;
}
ident_def opt_inherit TLCBR class_level_stmt_ls TRCBR {
$extern_export_decl_stmt = buildChapelStmt(buildClassDefExpr($ident_def,
$STRINGLITERAL,
AGGREGATE_RECORD,
$opt_inherit,
$class_level_stmt_ls,
FLAG_EXPORT,
@TRECORD.comment));
}
| TEXTERN opt_expr fn_decl_stmt {
$extern_export_decl_stmt = buildExternExportFunctionDecl(FLAG_EXTERN, $opt_expr, $fn_decl_stmt);
}
| TEXPORT opt_expr fn_decl_stmt {
$extern_export_decl_stmt = buildExternExportFunctionDecl(FLAG_EXPORT, $opt_expr, $fn_decl_stmt);
}
| TEXTERN opt_expr var_decl_type var_decl_stmt_inner_ls TSEMI {
const char* comment = context->latestComment;
context->latestComment = NULL;
$var_decl_type->insert(FLAG_EXTERN);
$extern_export_decl_stmt = buildVarDecls($var_decl_stmt_inner_ls, comment, $var_decl_type, $opt_expr);
}
| TEXPORT opt_expr var_decl_type var_decl_stmt_inner_ls TSEMI {
const char* comment = context->latestComment;
context->latestComment = NULL;
$var_decl_type->insert(FLAG_EXPORT);
$extern_export_decl_stmt = buildVarDecls($var_decl_stmt_inner_ls, comment, $var_decl_type, $opt_expr);
}
;
extern_block_stmt:
TEXTERN EXTERNCODE {
$extern_block_stmt = buildExternBlockStmt(astr($EXTERNCODE));
}
;
loop_stmt:
TDO stmt TWHILE expr TSEMI { $loop_stmt = DoWhileStmt::build($expr, $stmt); }
| TWHILE expr do_stmt { $loop_stmt = WhileDoStmt::build($expr, $do_stmt); }
| TWHILE ifvar do_stmt { $loop_stmt = WhileDoStmt::build($ifvar, $do_stmt); }
| TCOFORALL expr TIN expr opt_task_intent_ls do_stmt { $loop_stmt = buildCoforallLoopStmt($2 /* expr_2 */, $4 /* expr_4 */, $opt_task_intent_ls, $do_stmt); }
| TCOFORALL expr TIN zippered_iterator opt_task_intent_ls do_stmt { $loop_stmt = buildCoforallLoopStmt($expr, $zippered_iterator, $opt_task_intent_ls, $do_stmt, true); }
| TCOFORALL expr opt_task_intent_ls do_stmt { $loop_stmt = buildCoforallLoopStmt(NULL, $expr, $opt_task_intent_ls, $do_stmt); }
| TFOR expr TIN expr do_stmt { $loop_stmt = ForLoop::buildForLoop( $2 /* expr_2 */, $4 /* expr_4 */, $do_stmt, false, false); }
| TFOR expr TIN zippered_iterator do_stmt { $loop_stmt = ForLoop::buildForLoop( $expr, $zippered_iterator, $do_stmt, true, false); }
| TFOR expr do_stmt { $loop_stmt = ForLoop::buildForLoop(NULL, $expr, $do_stmt, false, false); }
| TFOR zippered_iterator do_stmt { $loop_stmt = ForLoop::buildForLoop(NULL, $zippered_iterator, $do_stmt, true, false); }
| TFOR TPARAM ident_def TIN expr do_stmt { $loop_stmt = buildParamForLoopStmt($ident_def, $expr, $do_stmt); }
| TFORALL expr TIN expr do_stmt { $loop_stmt = ForallStmt::build($2 /* expr_2 */, $4 /* expr_4 */, NULL, $do_stmt, false, false); }
| TFORALL expr TIN expr forall_intent_clause do_stmt { $loop_stmt = ForallStmt::build($2 /* expr_2 */, $4 /* expr_4 */, $forall_intent_clause, $do_stmt, false, false); }
| TFORALL expr TIN zippered_iterator do_stmt { $loop_stmt = ForallStmt::build($expr, $zippered_iterator, NULL, $do_stmt, true, false); }
| TFORALL expr TIN zippered_iterator forall_intent_clause do_stmt { $loop_stmt = ForallStmt::build($expr, $zippered_iterator, $forall_intent_clause, $do_stmt, true, false); }
| TFORALL expr do_stmt { $loop_stmt = ForallStmt::build(NULL, $expr, NULL, $do_stmt, false, false); }
| TFORALL expr forall_intent_clause do_stmt { $loop_stmt = ForallStmt::build(NULL, $expr, $forall_intent_clause, $do_stmt, false, false); }
| TFORALL zippered_iterator do_stmt { $loop_stmt = ForallStmt::build(NULL, $zippered_iterator, NULL, $do_stmt, true, false); }
| TFORALL zippered_iterator forall_intent_clause do_stmt { $loop_stmt = ForallStmt::build(NULL, $zippered_iterator, $forall_intent_clause, $do_stmt, true, false); }
| TFOREACH expr TIN expr do_stmt { $loop_stmt = foreachNotImplementedError(); }
| TFOREACH expr TIN expr forall_intent_clause do_stmt { $loop_stmt = foreachNotImplementedError(); }
| TFOREACH expr TIN zippered_iterator do_stmt { $loop_stmt = foreachNotImplementedError(); }
| TFOREACH expr TIN zippered_iterator forall_intent_clause do_stmt { $loop_stmt = foreachNotImplementedError(); }
| TFOREACH expr do_stmt { $loop_stmt = foreachNotImplementedError(); }
| TFOREACH expr forall_intent_clause do_stmt { $loop_stmt = foreachNotImplementedError(); }
| TFOREACH zippered_iterator do_stmt { $loop_stmt = foreachNotImplementedError(); }
| TFOREACH zippered_iterator forall_intent_clause do_stmt { $loop_stmt = foreachNotImplementedError(); }
| TLSBR expr_ls TIN expr TRSBR stmt {
if ($expr_ls->argList.length != 1)
USR_FATAL($expr, "invalid index expression");
$loop_stmt = ForallStmt::build($expr_ls->get(1)->remove(), $expr, NULL, new BlockStmt($stmt), false, true);
}
| TLSBR expr_ls TIN expr forall_intent_clause TRSBR stmt {
if ($expr_ls->argList.length != 1)
USR_FATAL($expr, "invalid index expression");
$loop_stmt = ForallStmt::build($expr_ls->get(1)->remove(), $expr, $forall_intent_clause, new BlockStmt($stmt), false, true);
}
| TLSBR expr_ls TIN zippered_iterator TRSBR stmt {
if ($expr_ls->argList.length != 1)
USR_FATAL($zippered_iterator, "invalid index expression");
$loop_stmt = ForallStmt::build($expr_ls->get(1)->remove(), $zippered_iterator, NULL, new BlockStmt($stmt), true, true);
}
| TLSBR expr_ls TIN zippered_iterator forall_intent_clause TRSBR stmt {
if ($expr_ls->argList.length != 1)
USR_FATAL($zippered_iterator, "invalid index expression");
$loop_stmt = ForallStmt::build($expr_ls->get(1)->remove(), $zippered_iterator, $forall_intent_clause, new BlockStmt($stmt), true, true);
}
| TLSBR expr_ls TRSBR stmt {
if ($expr_ls->argList.length > 1)
$loop_stmt = ForallStmt::build(NULL, new CallExpr("chpl__ensureDomainExpr", $expr_ls), NULL, new BlockStmt($stmt), false, true);
else
$loop_stmt = ForallStmt::build(NULL, $expr_ls->get(1)->remove(), NULL, new BlockStmt($stmt), false, true);
}
| TLSBR expr_ls forall_intent_clause TRSBR stmt {
if ($expr_ls->argList.length > 1)
$loop_stmt = ForallStmt::build(NULL, new CallExpr("chpl__ensureDomainExpr", $expr_ls), $forall_intent_clause, new BlockStmt($stmt), false, true);
else
$loop_stmt = ForallStmt::build(NULL, $expr_ls->get(1)->remove(), $forall_intent_clause, new BlockStmt($stmt), false, true);
}
| TLSBR zippered_iterator TRSBR stmt {
$loop_stmt = ForallStmt::build(NULL, $zippered_iterator, NULL, new BlockStmt($stmt), true, true);
}
| TLSBR zippered_iterator forall_intent_clause TRSBR stmt {
$loop_stmt = ForallStmt::build(NULL, $zippered_iterator, $forall_intent_clause, new BlockStmt($stmt), true, true);
}
;
zippered_iterator:
TZIP TLP expr_ls TRP { $zippered_iterator = new CallExpr(PRIM_ZIP, $expr_ls); }
;
if_stmt:
TIF expr TTHEN stmt %prec TNOELSE { $if_stmt = buildIfStmt($expr, $stmt); }
| TIF expr block_stmt %prec TNOELSE { $if_stmt = buildIfStmt($expr, $block_stmt); }
| TIF expr TTHEN stmt TELSE stmt { $if_stmt = buildIfStmt($expr, $4 /* stmt_4 */, $6 /* stmt_6 */); }
| TIF expr block_stmt TELSE stmt { $if_stmt = buildIfStmt($expr, $block_stmt, $stmt); }
| TIF ifvar TTHEN stmt %prec TNOELSE { $if_stmt = buildIfStmt($ifvar, $stmt); }
| TIF ifvar block_stmt %prec TNOELSE { $if_stmt = buildIfStmt($ifvar, $block_stmt); }
| TIF ifvar TTHEN stmt TELSE stmt { $if_stmt = buildIfStmt($ifvar, $4 /* stmt_4 */, $6 /* stmt_6 */); }
| TIF ifvar block_stmt TELSE stmt { $if_stmt = buildIfStmt($ifvar, $block_stmt, $stmt); }
| TIF expr assignop_ident expr TTHEN stmt %prec TNOELSE {
$if_stmt = buildIfStmt(convertAssignmentAndWarn($2 /* expr_2 */,$assignop_ident,$4 /* expr_4 */), $stmt); }
| TIF expr assignop_ident expr block_stmt %prec TNOELSE {
$if_stmt = buildIfStmt(convertAssignmentAndWarn($2 /* expr_2 */,$assignop_ident,$4 /* expr_4 */), $block_stmt); }
| TIF expr assignop_ident expr TTHEN stmt TELSE stmt {
$if_stmt = buildIfStmt(convertAssignmentAndWarn($2 /* expr_2 */,$assignop_ident,$4 /* expr_4 */), $6 /* stmt_6 */, $8 /* stmt_8 */); }
| TIF expr assignop_ident expr block_stmt TELSE stmt {
$if_stmt = buildIfStmt(convertAssignmentAndWarn($2 /* expr_2 */,$assignop_ident,$4 /* expr_4 */), $block_stmt, $stmt); }
;
ifvar:
TVAR ident_def TASSIGN expr { $ifvar = buildIfVar($ident_def, $expr, false); }
| TCONST ident_def TASSIGN expr { $ifvar = buildIfVar($ident_def, $expr, true); }
;
interface_stmt:
TINTERFACE ident_def TLP ifc_formal_ls TRP block_stmt { $interface_stmt = buildChapelStmt(InterfaceSymbol::buildDef($ident_def, $ifc_formal_ls, $block_stmt)); }
| TINTERFACE ident_def block_stmt { // mimick ifc_formal_ls for a single formal "Self"
DefExpr* formal = InterfaceSymbol::buildFormal("Self", INTENT_TYPE);
CallExpr* ls = new CallExpr(PRIM_ACTUALS_LIST, formal);
$interface_stmt = buildChapelStmt(InterfaceSymbol::buildDef($ident_def, ls, $block_stmt)); }
;
ifc_formal_ls:
ifc_formal { $ifc_formal_ls = new CallExpr(PRIM_ACTUALS_LIST, $ifc_formal); }
| ifc_formal_ls[rhs_1] TCOMMA ifc_formal { $rhs_1->insertAtTail($ifc_formal); }
;
ifc_formal:
// implicitly 'type' intent, could specify explicitly - see #16966
ident_def { $ifc_formal = InterfaceSymbol::buildFormal($//, INTENT_TYPE); }
;
implements_type_ident:
TIDENT { $implements_type_ident = $TIDENT; }
| TBOOL { $implements_type_ident = "bool"; }
| TINT { $implements_type_ident = "int"; }
| TUINT { $implements_type_ident = "uint"; }
| TREAL { $implements_type_ident = "real"; }
| TIMAG { $implements_type_ident = "imag"; }
| TCOMPLEX { $implements_type_ident = "complex"; }
| TBYTES { $implements_type_ident = "bytes"; }
| TSTRING { $implements_type_ident = "string"; }
| TLOCALE { $implements_type_ident = "locale"; }
| TNOTHING { $implements_type_ident = "nothing"; }
| TVOID { $implements_type_ident = "void"; }
| implements_type_error_ident { $implements_type_ident = $implements_type_error_ident;
USR_FATAL_CONT("'%s' is not allowed to \"implement\" an interface", $implements_type_error_ident); }
;
implements_type_error_ident:
TNONE { $implements_type_error_ident = "none"; }
| TTHIS { $implements_type_error_ident = "this"; }
| TFALSE { $implements_type_error_ident = "false"; }
| TTRUE { $implements_type_error_ident = "true"; }
/* it would be nice to include these, alas they cause shift/reduce conflicts:
| TSYNC { $$ = "sync"; }
| TSINGLE { $$ = "single"; }
| TOWNED { $$ = "owned"; }
| TSHARED { $$ = "shared"; }
| TBORROWED { $$ = "borrowed"; }
| TUNMANAGED { $$ = "unmanaged"; }
*/
| TDOMAIN { $implements_type_error_ident = "domain"; }
| TINDEX { $implements_type_error_ident = "index"; }
;
implements_stmt:
TIMPLEMENTS ident_def TLP actual_ls TRP TSEMI { $implements_stmt = buildChapelStmt(ImplementsStmt::build($ident_def, $actual_ls, NULL)); }
| implements_type_ident TIMPLEMENTS ident_def TSEMI { CallExpr* act = new CallExpr(PRIM_ACTUALS_LIST, new UnresolvedSymExpr($implements_type_ident));
$implements_stmt = buildChapelStmt(ImplementsStmt::build($ident_def, act, NULL)); }
| implements_type_ident TIMPLEMENTS ident_def TLP actual_ls TRP TSEMI { $actual_ls->insertAtHead(new UnresolvedSymExpr($implements_type_ident));
$implements_stmt = buildChapelStmt(ImplementsStmt::build($ident_def, $actual_ls, NULL)); }
;
ifc_constraint:
TIMPLEMENTS ident_def TLP actual_ls TRP { $ifc_constraint = IfcConstraint::build($ident_def, $actual_ls); }
| implements_type_ident TIMPLEMENTS ident_def { CallExpr* act = new CallExpr(PRIM_ACTUALS_LIST, new UnresolvedSymExpr($implements_type_ident));
$ifc_constraint = IfcConstraint::build($ident_def, act); }
| implements_type_ident TIMPLEMENTS ident_def TLP actual_ls TRP { $actual_ls->insertAtHead(new UnresolvedSymExpr($implements_type_ident));
$ifc_constraint = IfcConstraint::build($ident_def, $actual_ls); }
;
defer_stmt:
TDEFER stmt { $defer_stmt = DeferStmt::build($stmt); }
;
try_stmt:
TTRY expr TSEMI { $try_stmt = TryStmt::build(false, $expr); }
| TTRYBANG expr TSEMI { $try_stmt = TryStmt::build(true, $expr); }
| TTRY assignment_stmt { $try_stmt = TryStmt::build(false, $assignment_stmt); }
| TTRYBANG assignment_stmt { $try_stmt = TryStmt::build(true, $assignment_stmt); }
| TTRY block_stmt catch_stmt_ls { $try_stmt = TryStmt::build(false, $block_stmt, $catch_stmt_ls); }
| TTRYBANG block_stmt catch_stmt_ls { $try_stmt = TryStmt::build(true, $block_stmt, $catch_stmt_ls); }
;
catch_stmt_ls:
{ $catch_stmt_ls = buildChapelStmt(); }
| catch_stmt_ls[rhs_1] catch_stmt { $rhs_1->insertAtTail($catch_stmt); }
;
catch_stmt:
TCATCH block_stmt { $catch_stmt = CatchStmt::build($block_stmt); }
| TCATCH catch_expr block_stmt { $catch_stmt = CatchStmt::build($catch_expr, $block_stmt); }
| TCATCH TLP catch_expr TRP block_stmt { $catch_stmt = CatchStmt::build($catch_expr, $block_stmt); }
;
catch_expr:
ident_def { $catch_expr = new DefExpr(new VarSymbol($ident_def), NULL, new UnresolvedSymExpr("Error")); }
| ident_def TCOLON expr { $catch_expr = new DefExpr(new VarSymbol($ident_def), NULL, $expr); }
;
throw_stmt:
TTHROW expr TSEMI { $throw_stmt = buildPrimitiveStmt(PRIM_THROW, $expr); }
;
select_stmt:
TSELECT expr TLCBR when_stmt_ls TRCBR { $select_stmt = buildChapelStmt(buildSelectStmt($expr, $when_stmt_ls)); }
| TSELECT expr TLCBR error TRCBR { $select_stmt = buildErrorStandin(); }
;
when_stmt_ls:
{ $when_stmt_ls = buildChapelStmt(); }
| when_stmt_ls[rhs_1] when_stmt { $rhs_1->insertAtTail($when_stmt); }
;
when_stmt:
TWHEN expr_ls do_stmt { $when_stmt = new CondStmt(new CallExpr(PRIM_WHEN, $expr_ls), $do_stmt); }
| TOTHERWISE stmt { $when_stmt = new CondStmt(new CallExpr(PRIM_WHEN), $stmt); }
| TOTHERWISE TDO stmt { $when_stmt = new CondStmt(new CallExpr(PRIM_WHEN), $stmt); }
;
class_decl_stmt:
class_tag ident_def opt_inherit TLCBR class_level_stmt_ls TRCBR {
$class_decl_stmt = buildChapelStmt(buildClassDefExpr($ident_def,
NULL,
$class_tag,
$opt_inherit,
$class_level_stmt_ls,
FLAG_UNKNOWN,
@class_tag.comment));
}
| class_tag ident_def opt_inherit TLCBR error TRCBR {
$class_decl_stmt = buildChapelStmt(buildClassDefExpr($ident_def,
NULL,
$class_tag,
$opt_inherit,
new BlockStmt(),
FLAG_UNKNOWN,
@class_tag.comment));
}
/* see also extern_decl_stmt */
;
class_tag:
TCLASS {
$class_tag = AGGREGATE_CLASS;
@$.comment = context->latestComment;
context->latestComment = NULL;
}
| TRECORD {
$class_tag = AGGREGATE_RECORD;
@$.comment = context->latestComment;
context->latestComment = NULL;
}
| TUNION {
$class_tag = AGGREGATE_UNION;
@$.comment = context->latestComment;
context->latestComment = NULL;
}
;
opt_inherit:
{ $opt_inherit = NULL; }
| TCOLON expr_ls { $opt_inherit = $expr_ls; }
;
class_level_stmt_ls:
/* nothing */ { $class_level_stmt_ls = new BlockStmt(); }
| class_level_stmt_ls[rhs_1] class_level_stmt { $rhs_1->insertAtTail($class_level_stmt); }
| class_level_stmt_ls[rhs_1] pragma_ls class_level_stmt { $rhs_1->insertAtTail(buildPragmaStmt($pragma_ls, $class_level_stmt)); }
;
enum_decl_stmt:
enum_header ident_def TLCBR enum_ls TRCBR {
EnumType* pdt = $enum_header;
for_vector(DefExpr, ec, *$enum_ls) {
ec->sym->type = pdt;
pdt->constants.insertAtTail(ec);
if (pdt->defaultValue == NULL) {
pdt->defaultValue = ec->sym;
}
}
delete $enum_ls;
pdt->doc = @enum_header.comment;
TypeSymbol* pst = new TypeSymbol($ident_def, pdt);
$enum_header->symbol = pst;
$enum_decl_stmt = buildChapelStmt(new DefExpr(pst));
}
| enum_header ident_def TLCBR error TRCBR {
$enum_decl_stmt = buildErrorStandin();
}
;
enum_header:
TENUM {
$enum_header = new EnumType();
@$.comment = context->latestComment;
context->latestComment = NULL;
}
;
enum_ls:
enum_item {
$enum_ls = new std::vector<DefExpr*>();
$enum_ls->push_back($enum_item);
//$enum_ls->doc = context->latestComment;
// start here for enabling documentation of enum constants
//context->latestComment = NULL;
}
| enum_ls[rhs_1] TCOMMA {
$$ /* enum_ls */ = $rhs_1;
}
| enum_ls[rhs_1] TCOMMA enum_item {
$rhs_1->push_back($enum_item);
}
;
enum_item:
ident_def { $enum_item = new DefExpr(new EnumSymbol($ident_def)); }
| ident_def TASSIGN expr { $enum_item = new DefExpr(new EnumSymbol($ident_def), $expr); }
;
lambda_decl_expr:
TLAMBDA {
captureTokens = 1;
captureString.clear();
}
req_formal_ls {
captureTokens = 0;
$req_formal_ls->userString = astr(captureString);
}
opt_ret_tag opt_type opt_lifetime_where function_body_stmt {
$req_formal_ls->retTag = $opt_ret_tag;
if ($opt_ret_tag == RET_REF || $opt_ret_tag == RET_CONST_REF)
USR_FATAL("'ref' return types are not allowed in lambdas");
if ($opt_ret_tag == RET_PARAM)
USR_FATAL("'param' return types are not allowed in lambdas");
if ($opt_ret_tag == RET_TYPE)
USR_FATAL("'type' return types are not allowed in lambdas");
if ($opt_type)
$req_formal_ls->retExprType = new BlockStmt($opt_type, BLOCK_SCOPELESS);
if ($opt_lifetime_where.where)
$req_formal_ls->where = new BlockStmt($opt_lifetime_where.where);
if ($opt_lifetime_where.lifetime)
$req_formal_ls->lifetimeConstraints = new BlockStmt($opt_lifetime_where.lifetime);
$req_formal_ls->insertAtTail($function_body_stmt);
$lambda_decl_expr = new DefExpr(buildLambda($req_formal_ls));
}
;
linkage_spec:
{
$linkage_spec = new FnSymbol("");
}
| TINLINE {
$linkage_spec = new FnSymbol("");
$linkage_spec->addFlag(FLAG_INLINE);
}
| TOVERRIDE {
$linkage_spec = new FnSymbol("");
$linkage_spec->addFlag(FLAG_OVERRIDE);
}
;
fn_decl_stmt:
linkage_spec proc_iter_or_op {
// Capture the latest comment
@proc_iter_or_op.comment = context->latestComment;
context->latestComment = NULL;
// Sets up to capture tokens while parsing the next grammar nonterminal.
captureTokens = 1;
captureString.clear();
}
fn_decl_stmt_inner {
// Stop capturing and save the result.
captureTokens = 0;
$fn_decl_stmt_inner->userString = astr(captureString);
}
opt_ret_tag opt_ret_type opt_throws_error opt_lifetime_where opt_function_body_stmt {
FnSymbol* fn = $fn_decl_stmt_inner;
FnSymbol* linkageFn = $linkage_spec;
fn->copyFlags($linkage_spec);
if (*linkageFn->name)
// The user explicitly named this function (controls mangling).
fn->cname = linkageFn->name;
else if (linkageFn->numFormals() == 1)
// cname should be set based upon param
fn->insertFormalAtTail(linkageFn->getFormal(1));
if ($proc_iter_or_op == ProcIterOp_ITER)
{
if (fn->hasFlag(FLAG_EXTERN))
USR_FATAL_CONT(fn, "'iter' is not legal with 'extern'");
fn->addFlag(FLAG_ITERATOR_FN);
}
if ($proc_iter_or_op == ProcIterOp_OP) {
fn->addFlag(FLAG_OPERATOR);
if (fn->_this != NULL) {
updateOpThisTagOrErr(fn);
setupTypeIntentArg(toArgSymbol(fn->_this));
}
}
$fn_decl_stmt = buildFunctionDecl($fn_decl_stmt_inner, $opt_ret_tag, $opt_ret_type, $opt_throws_error, $opt_lifetime_where.where, $opt_lifetime_where.lifetime, $opt_function_body_stmt, @proc_iter_or_op.comment);
context->latestComment = NULL;
}
;
fn_decl_stmt_inner:
opt_this_intent_tag fn_ident opt_formal_ls {
$fn_decl_stmt_inner = buildFunctionSymbol($opt_formal_ls, $fn_ident, $opt_this_intent_tag, NULL);
}
| opt_this_intent_tag assignop_ident opt_formal_ls {
$fn_decl_stmt_inner = buildFunctionSymbol($opt_formal_ls, $assignop_ident, $opt_this_intent_tag, NULL);
$fn_decl_stmt_inner->addFlag(FLAG_ASSIGNOP);
}
| opt_this_intent_tag fn_decl_receiver_expr TDOT fn_ident opt_formal_ls {
$fn_decl_stmt_inner = buildFunctionSymbol($opt_formal_ls, $fn_ident, $opt_this_intent_tag, $fn_decl_receiver_expr);
}
| opt_this_intent_tag fn_decl_receiver_expr TDOT assignop_ident opt_formal_ls {
$fn_decl_stmt_inner = buildFunctionSymbol($opt_formal_ls, $assignop_ident, $opt_this_intent_tag, $fn_decl_receiver_expr);
$fn_decl_stmt_inner->addFlag(FLAG_ASSIGNOP);
}
| opt_this_intent_tag error opt_formal_ls {
$fn_decl_stmt_inner = buildFunctionSymbol($opt_formal_ls, "dummy", INTENT_BLANK, NULL);
}
;
fn_decl_receiver_expr:
ident_expr
| TLP expr TRP { $fn_decl_receiver_expr = $expr; }
;
fn_ident:
ident_fn_def { $fn_ident = $ident_fn_def; }
| TBAND { $fn_ident = "&"; }
| TBOR { $fn_ident = "|"; }
| TBXOR { $fn_ident = "^"; }
| TBNOT { $fn_ident = "~"; }
| TEQUAL { $fn_ident = "=="; }
| TNOTEQUAL { $fn_ident = "!="; }
| TLESSEQUAL { $fn_ident = "<="; }
| TGREATEREQUAL { $fn_ident = ">="; }
| TLESS { $fn_ident = "<"; }
| TGREATER { $fn_ident = ">"; }
| TPLUS { $fn_ident = "+"; }
| TMINUS { $fn_ident = "-"; }
| TSTAR { $fn_ident = "*"; }
| TDIVIDE { $fn_ident = "/"; }
| TSHIFTLEFT { $fn_ident = "<<"; }
| TSHIFTRIGHT { $fn_ident = ">>"; }
| TMOD { $fn_ident = "%"; }
| TEXP { $fn_ident = "**"; }
| TBANG { $fn_ident = "!"; }
| TBY { $fn_ident = "chpl_by"; }
| THASH { $fn_ident = "#"; }
| TALIGN { $fn_ident = "chpl_align"; }
| TSWAP { $fn_ident = "<=>"; }
| TIO { $fn_ident = "<~>"; }
| TINITEQUALS { $fn_ident = "init="; }
| TCOLON { $fn_ident = ":"; }
| ident_def TBANG { $fn_ident = astr($ident_def, "!"); }
;
assignop_ident:
TASSIGN { $assignop_ident = "="; }
| TASSIGNPLUS { $assignop_ident = "+="; }
| TASSIGNMINUS { $assignop_ident = "-="; }
| TASSIGNMULTIPLY { $assignop_ident = "*="; }
| TASSIGNDIVIDE { $assignop_ident = "/="; }
| TASSIGNMOD { $assignop_ident = "%="; }
| TASSIGNEXP { $assignop_ident = "**="; }
| TASSIGNBAND { $assignop_ident = "&="; }
| TASSIGNBOR { $assignop_ident = "|="; }
| TASSIGNBXOR { $assignop_ident = "^="; }
| TASSIGNSR { $assignop_ident = ">>="; }
| TASSIGNSL { $assignop_ident = "<<="; }
;
opt_formal_ls:
{ $opt_formal_ls = new FnSymbol("_"); $opt_formal_ls->addFlag(FLAG_NO_PARENS); }
| TLP formal_ls TRP { $opt_formal_ls = $formal_ls; }
;
req_formal_ls:
TLP formal_ls TRP { $req_formal_ls = $formal_ls; }
;
formal_ls:
{ $formal_ls = buildFunctionFormal(NULL, NULL); }
| formal { $formal_ls = buildFunctionFormal(NULL, $formal); }
| formal_ls[rhs_1] TCOMMA formal { $$ /* formal_ls */ = buildFunctionFormal($rhs_1, $formal); }
;
formal:
opt_intent_tag ident_def opt_formal_type opt_init_expr { $formal = buildArgDefExpr($opt_intent_tag, $ident_def, $opt_formal_type, $opt_init_expr, NULL); }
| pragma_ls opt_intent_tag ident_def opt_formal_type opt_init_expr { $formal = buildPragmaDefExpr($pragma_ls, buildArgDefExpr($opt_intent_tag, $ident_def, $opt_formal_type, $opt_init_expr, NULL)); }
| opt_intent_tag ident_def opt_formal_type var_arg_expr { $formal = buildArgDefExpr($opt_intent_tag, $ident_def, $opt_formal_type, NULL, $var_arg_expr); }
| pragma_ls opt_intent_tag ident_def opt_formal_type var_arg_expr { $formal = buildPragmaDefExpr($pragma_ls, buildArgDefExpr($opt_intent_tag, $ident_def, $opt_formal_type, NULL, $var_arg_expr)); }
| opt_intent_tag TLP tuple_var_decl_stmt_inner_ls TRP opt_formal_type opt_init_expr { $formal = buildTupleArgDefExpr($opt_intent_tag, $tuple_var_decl_stmt_inner_ls, $opt_formal_type, $opt_init_expr); }
| opt_intent_tag TLP tuple_var_decl_stmt_inner_ls TRP opt_formal_type var_arg_expr { USR_FATAL("variable-length argument may not be grouped in a tuple"); }
;
opt_intent_tag:
{ $opt_intent_tag = INTENT_BLANK; }
| required_intent_tag { $opt_intent_tag = $required_intent_tag; }
;
required_intent_tag:
TIN { $required_intent_tag = INTENT_IN; }
| TINOUT { $required_intent_tag = INTENT_INOUT; }
| TOUT { $required_intent_tag = INTENT_OUT; }
| TCONST { $required_intent_tag = INTENT_CONST; }
| TCONST TIN { $required_intent_tag = INTENT_CONST_IN; }
| TCONST TREF { $required_intent_tag = INTENT_CONST_REF; }
| TPARAM { $required_intent_tag = INTENT_PARAM; }
| TREF { $required_intent_tag = INTENT_REF; }
| TTYPE { $required_intent_tag = INTENT_TYPE; }
;
opt_this_intent_tag:
{ $opt_this_intent_tag = INTENT_BLANK; }
| TPARAM { $opt_this_intent_tag = INTENT_PARAM; }
| TREF { $opt_this_intent_tag = INTENT_REF; }
| TCONST TREF { $opt_this_intent_tag = INTENT_CONST_REF; }
| TCONST { $opt_this_intent_tag = INTENT_CONST; }
| TTYPE { $opt_this_intent_tag = INTENT_TYPE; }
;
proc_iter_or_op:
TPROC { $proc_iter_or_op = ProcIterOp_PROC; }
| TITER { $proc_iter_or_op = ProcIterOp_ITER; }
| TOPERATOR { $proc_iter_or_op = ProcIterOp_OP; }
;
opt_ret_tag:
{ $opt_ret_tag = RET_VALUE; }
| TCONST { $opt_ret_tag = RET_VALUE; }
| TCONST TREF { $opt_ret_tag = RET_CONST_REF; }
| TREF { $opt_ret_tag = RET_REF; }
| TPARAM { $opt_ret_tag = RET_PARAM; }
| TTYPE { $opt_ret_tag = RET_TYPE; }
;
opt_throws_error:
{ $opt_throws_error = false; }
| TTHROWS { $opt_throws_error = true; }
;
opt_function_body_stmt:
TSEMI { $opt_function_body_stmt = NULL; }
| function_body_stmt
;
function_body_stmt:
block_stmt
| return_stmt { $function_body_stmt = new BlockStmt($return_stmt); }
;
query_expr:
TQUERIEDIDENT { $query_expr = buildQueriedExpr($TQUERIEDIDENT); }
;
var_arg_expr:
TDOTDOTDOT { $var_arg_expr = new SymExpr(gUninstantiated); }
| TDOTDOTDOT expr { $var_arg_expr = $expr; }
| TDOTDOTDOT query_expr { if (DefExpr* def = toDefExpr($query_expr)) {
def->sym->addFlag(FLAG_PARAM);
}
$var_arg_expr = $query_expr;
}
;
opt_lifetime_where:
{ $opt_lifetime_where = makeWhereAndLifetime(NULL, NULL); }
| TWHERE expr { $opt_lifetime_where = makeWhereAndLifetime($expr, NULL); }
| TLIFETIME lifetime_components_expr { $opt_lifetime_where = makeWhereAndLifetime(NULL, $lifetime_components_expr); }
| TWHERE expr TLIFETIME lifetime_components_expr { $opt_lifetime_where = makeWhereAndLifetime($expr, $lifetime_components_expr); }
| TLIFETIME lifetime_components_expr TWHERE expr { $opt_lifetime_where = makeWhereAndLifetime($expr, $lifetime_components_expr); }
;
lifetime_components_expr:
lifetime_expr { $lifetime_components_expr = $lifetime_expr; }
| lifetime_components_expr[rhs_1] TCOMMA lifetime_expr { $$ /* lifetime_components_expr */ = new CallExpr(",", $rhs_1, $lifetime_expr); }
;
lifetime_expr:
lifetime_ident TASSIGN lifetime_ident {$lifetime_expr = new CallExpr("=", $1 /* lifetime_ident_1 */, $3 /* lifetime_ident_3 */);}
| lifetime_ident TLESS lifetime_ident {$lifetime_expr = new CallExpr("<", $1 /* lifetime_ident_1 */, $3 /* lifetime_ident_3 */);}
| lifetime_ident TLESSEQUAL lifetime_ident {$lifetime_expr = new CallExpr("<=", $1 /* lifetime_ident_1 */, $3 /* lifetime_ident_3 */);}
| lifetime_ident TEQUAL lifetime_ident {$lifetime_expr = new CallExpr("==", $1 /* lifetime_ident_1 */, $3 /* lifetime_ident_3 */);}
| lifetime_ident TGREATER lifetime_ident {$lifetime_expr = new CallExpr(">", $1 /* lifetime_ident_1 */, $3 /* lifetime_ident_3 */);}
| lifetime_ident TGREATEREQUAL lifetime_ident {$lifetime_expr = new CallExpr(">=", $1 /* lifetime_ident_1 */, $3 /* lifetime_ident_3 */);}
| TRETURN lifetime_ident { $lifetime_expr = new CallExpr(PRIM_RETURN, $lifetime_ident); }
;
lifetime_ident:
TIDENT { $lifetime_ident = new CallExpr(PRIM_LIFETIME_OF, new UnresolvedSymExpr($TIDENT)); }
| TTHIS { $lifetime_ident = new CallExpr(PRIM_LIFETIME_OF, new UnresolvedSymExpr("this")); }
;
type_alias_decl_stmt:
TTYPE type_alias_decl_stmt_inner TSEMI { $type_alias_decl_stmt = $type_alias_decl_stmt_inner; }
| TCONFIG TTYPE type_alias_decl_stmt_inner TSEMI { $type_alias_decl_stmt = handleConfigTypes($type_alias_decl_stmt_inner); }
| TEXTERN TTYPE type_alias_decl_stmt_inner TSEMI { $type_alias_decl_stmt = convertTypesToExtern($type_alias_decl_stmt_inner); }
;
type_alias_decl_stmt_inner:
ident_def opt_init_type {
VarSymbol* var = new VarSymbol($ident_def);
var->addFlag(FLAG_TYPE_VARIABLE);
var->doc = context->latestComment;
context->latestComment = NULL;
DefExpr* def = new DefExpr(var, $opt_init_type);
$type_alias_decl_stmt_inner = buildChapelStmt(def);
}
| ident_def opt_init_type TCOMMA type_alias_decl_stmt_inner[rhs_1] {
VarSymbol* var = new VarSymbol($ident_def);
var->addFlag(FLAG_TYPE_VARIABLE);
var->doc = context->latestComment;
context->latestComment = NULL;
DefExpr* def = new DefExpr(var, $opt_init_type);
$rhs_1->insertAtHead(def);
$$ /* type_alias_decl_stmt_inner */ = buildChapelStmt($rhs_1);
}
;
opt_init_type:
{ $opt_init_type = NULL; }
| TASSIGN type_level_expr { $opt_init_type = $type_level_expr; }
| TASSIGN array_type { $opt_init_type = buildForallLoopExprFromArrayType($array_type); } // Cannot be a type_level_expr as expr inherits from type_level_expr.
;
var_decl_type:
TPARAM { $var_decl_type = buildVarDeclFlags(FLAG_PARAM); }
| TCONST { $var_decl_type = buildVarDeclFlags(FLAG_CONST); }
| TREF { $var_decl_type = buildVarDeclFlags(FLAG_REF_VAR); }
| TCONST TREF { $var_decl_type = buildVarDeclFlags(FLAG_CONST, FLAG_REF_VAR); }
| TVAR { $var_decl_type = buildVarDeclFlags(); }
;
var_decl_stmt:
TCONFIG var_decl_type var_decl_stmt_inner_ls TSEMI {
$var_decl_type->insert(FLAG_CONFIG);
$var_decl_stmt = buildVarDecls($var_decl_stmt_inner_ls, context->latestComment, $var_decl_type);
context->latestComment = NULL;
}
| var_decl_type var_decl_stmt_inner_ls TSEMI {
$var_decl_stmt = buildVarDecls($var_decl_stmt_inner_ls, context->latestComment, $var_decl_type);
context->latestComment = NULL;
}
;
var_decl_stmt_inner_ls:
var_decl_stmt_inner
| var_decl_stmt_inner_ls[rhs_1] TCOMMA var_decl_stmt_inner {
for_alist(expr, $var_decl_stmt_inner->body)
$rhs_1->insertAtTail(expr->remove());
}
;
var_decl_stmt_inner:
ident_def opt_type opt_init_expr { $var_decl_stmt_inner = buildChapelStmt(new DefExpr(new VarSymbol($ident_def), $opt_init_expr, $opt_type)); }
| TLP tuple_var_decl_stmt_inner_ls TRP opt_type opt_init_expr { $var_decl_stmt_inner = buildTupleVarDeclStmt($tuple_var_decl_stmt_inner_ls, $opt_type, $opt_init_expr); }
;
tuple_var_decl_component:
TUNDERSCORE { $tuple_var_decl_component = new DefExpr(new VarSymbol("chpl__tuple_blank")); }
| ident_def { $tuple_var_decl_component = new DefExpr(new VarSymbol($ident_def)); }
| TLP tuple_var_decl_stmt_inner_ls TRP { $tuple_var_decl_component = $tuple_var_decl_stmt_inner_ls; }
;
tuple_var_decl_stmt_inner_ls:
tuple_var_decl_component { $tuple_var_decl_stmt_inner_ls = buildChapelStmt($tuple_var_decl_component); }
| tuple_var_decl_component TCOMMA { $tuple_var_decl_stmt_inner_ls = buildChapelStmt($tuple_var_decl_component); }
| tuple_var_decl_component TCOMMA tuple_var_decl_stmt_inner_ls[rhs_1] { $$ /* tuple_var_decl_stmt_inner_ls */ = ($rhs_1->insertAtHead($tuple_var_decl_component), $rhs_1); }
;
opt_init_expr:
{ $opt_init_expr = NULL; }
| TASSIGN TNOINIT { $opt_init_expr = new SymExpr(gNoInit); }
| TASSIGN opt_try_expr { $opt_init_expr = $opt_try_expr; }
;
ret_array_type:
TLSBR TRSBR type_level_expr { $ret_array_type = new CallExpr("chpl__buildArrayRuntimeType", gNil, $type_level_expr); }
| TLSBR TRSBR { $ret_array_type = new CallExpr("chpl__buildArrayRuntimeType", gNil, NULL); }
| TLSBR expr_ls TRSBR type_level_expr { $ret_array_type = new CallExpr("chpl__buildArrayRuntimeType",
new CallExpr("chpl__ensureDomainExpr", $expr_ls), $type_level_expr);
}
| TLSBR expr_ls TRSBR { $ret_array_type = new CallExpr("chpl__buildArrayRuntimeType",
new CallExpr("chpl__ensureDomainExpr", $expr_ls), NULL);
}
| TLSBR TRSBR ret_array_type[rhs_1] { $$ /* ret_array_type */ = new CallExpr("chpl__buildArrayRuntimeType", gNil, $rhs_1); }
| TLSBR expr_ls TRSBR ret_array_type[rhs_1] { $$ /* ret_array_type */ = new CallExpr("chpl__buildArrayRuntimeType",
new CallExpr("chpl__ensureDomainExpr", $expr_ls), $rhs_1);
}
| TLSBR error TRSBR {
$ret_array_type = new CallExpr(PRIM_ERROR);
}
;
opt_ret_type:
{ $opt_ret_type = NULL; }
| TCOLON type_level_expr { $opt_ret_type = $type_level_expr; }
| TCOLON ret_array_type { $opt_ret_type = $ret_array_type; }
| TCOLON reserved_type_ident_use { $opt_ret_type = new UnresolvedSymExpr($reserved_type_ident_use); }
| error { $opt_ret_type = NULL; }
;
opt_type:
{ $opt_type = NULL; }
| TCOLON type_level_expr { $opt_type = $type_level_expr; }
| TCOLON array_type { $opt_type = $array_type; }
| TCOLON reserved_type_ident_use { $opt_type = new UnresolvedSymExpr($reserved_type_ident_use); }
| error { $opt_type = NULL; }
;
array_type:
TLSBR expr_ls TRSBR type_level_expr { $array_type = new CallExpr("chpl__buildArrayRuntimeType",
new CallExpr("chpl__ensureDomainExpr", $expr_ls), $type_level_expr);
}
| TLSBR expr_ls TRSBR array_type[rhs_1] { $$ /* array_type */ = new CallExpr("chpl__buildArrayRuntimeType",
new CallExpr("chpl__ensureDomainExpr", $expr_ls), $rhs_1);
}
| TLSBR expr_ls TIN expr TRSBR type_level_expr {
if ($expr_ls->argList.length != 1)
USR_FATAL($expr, "invalid index expression");
$array_type = new CallExpr("chpl__buildArrayRuntimeType",
new CallExpr("chpl__ensureDomainExpr", $expr), $type_level_expr, $expr_ls->get(1)->remove(),
new CallExpr("chpl__ensureDomainExpr", $expr->copy()));
}
| TLSBR error TRSBR {
$array_type = new CallExpr(PRIM_ERROR);
}
;
opt_formal_array_elt_type:
{ $opt_formal_array_elt_type = NULL; }
| type_level_expr { $opt_formal_array_elt_type = $type_level_expr; }
| query_expr { $opt_formal_array_elt_type = $query_expr; }
;
formal_array_type:
TLSBR TRSBR opt_formal_array_elt_type { $formal_array_type = new CallExpr("chpl__buildArrayRuntimeType", gNil, $opt_formal_array_elt_type); }
| TLSBR expr_ls TRSBR opt_formal_array_elt_type { $formal_array_type = buildFormalArrayType($expr_ls, $opt_formal_array_elt_type); }
// Johnk: Unclear to me what the type should be when [<range>][] <type> is encountered.
// At present buildArrayRuntimeType is undefined when gNil is passed and
// the second argument is a formal_array_type[rhs_1].
| TLSBR TRSBR formal_array_type[rhs_2] { $$ /* formal_array_type */ = new CallExpr("chpl__buildArrayRuntimeType", gNil, $rhs_2); }
| TLSBR expr_ls TRSBR formal_array_type[rhs_1] { $$ /* formal_array_type */ = buildFormalArrayType($expr_ls, $rhs_1); }
| TLSBR expr_ls TIN expr TRSBR opt_formal_array_elt_type { $formal_array_type = buildFormalArrayType($expr, $opt_formal_array_elt_type, $expr_ls); }
;
opt_formal_type:
{ $opt_formal_type = NULL; }
| TCOLON type_level_expr { $opt_formal_type = $type_level_expr; }
| TCOLON query_expr { $opt_formal_type = $query_expr; }
| TCOLON reserved_type_ident_use { $opt_formal_type = new UnresolvedSymExpr($reserved_type_ident_use); }
| TCOLON formal_array_type { $opt_formal_type = $formal_array_type; }
;
expr_ls:
expr { $expr_ls = new CallExpr(PRIM_ACTUALS_LIST, $expr); }
| query_expr { $expr_ls = new CallExpr(PRIM_ACTUALS_LIST, $query_expr); }
| expr_ls[rhs_1] TCOMMA expr { $rhs_1->insertAtTail($expr); }
| expr_ls[rhs_1] TCOMMA query_expr { $rhs_1->insertAtTail($query_expr); }
;
simple_expr_ls:
expr { $simple_expr_ls = new CallExpr(PRIM_ACTUALS_LIST, $expr);}
| simple_expr_ls[rhs_1] TCOMMA expr { $rhs_1->insertAtTail($expr); }
;
tuple_component:
TUNDERSCORE { $tuple_component = new UnresolvedSymExpr("chpl__tuple_blank"); }
| opt_try_expr { $tuple_component = $opt_try_expr; }
| query_expr { $tuple_component = $query_expr; }
;
tuple_expr_ls:
tuple_component TCOMMA tuple_component { $tuple_expr_ls = new CallExpr(PRIM_ACTUALS_LIST, $1 /* tuple_component_1 */, $3 /* tuple_component_3 */); }
| tuple_expr_ls[rhs_1] TCOMMA tuple_component { $rhs_1->insertAtTail($tuple_component); }
;
opt_actual_ls:
{ $opt_actual_ls = new CallExpr(PRIM_ACTUALS_LIST); }
| actual_ls
;
actual_ls:
actual_expr { $actual_ls = new CallExpr(PRIM_ACTUALS_LIST, $actual_expr); }
| actual_ls[rhs_1] TCOMMA actual_expr { $rhs_1->insertAtTail($actual_expr); }
;
actual_expr:
ident_use TASSIGN query_expr { $actual_expr = buildNamedActual($ident_use, $query_expr); }
| ident_use TASSIGN opt_try_expr { $actual_expr = buildNamedActual($ident_use, $opt_try_expr); }
| query_expr { $actual_expr = $query_expr; }
| opt_try_expr { $actual_expr = $opt_try_expr; }
;
ident_expr:
ident_use { $ident_expr = new UnresolvedSymExpr($ident_use); }
| scalar_type { $ident_expr = $scalar_type; }
;
type_level_expr:
sub_type_level_expr %prec TNOELSE { $type_level_expr = $sub_type_level_expr; }
| sub_type_level_expr TQUESTION %prec TQUESTION { $type_level_expr = new CallExpr( PRIM_TO_NILABLE_CLASS_CHECKED, $sub_type_level_expr); }
| TQUESTION { $type_level_expr = new SymExpr(gUninstantiated); }
;
sub_type_level_expr:
nil_expr
| lhs_expr // var b: a.type || (?,?) || foo()
| cond_expr // type b = if b then uint else int
| unary_op_expr // We allow binary exprs as types...why not unary?
| binary_op_expr // tuples, expr dmapped expr, overloaded binary ops
| TSINGLE expr { $sub_type_level_expr = new CallExpr( "_singlevar", $expr); }
| TINDEX TLP opt_actual_ls TRP { $sub_type_level_expr = new CallExpr("chpl__buildIndexType", $opt_actual_ls); }
| TDOMAIN TLP opt_actual_ls TRP { $sub_type_level_expr = new CallExpr("chpl__buildDomainRuntimeType", new UnresolvedSymExpr("defaultDist"), $opt_actual_ls); }
| TSUBDOMAIN TLP opt_actual_ls TRP { $sub_type_level_expr = new CallExpr("chpl__buildSubDomainType", $opt_actual_ls); }
| TSPARSE TSUBDOMAIN TLP actual_expr TRP { $sub_type_level_expr = new CallExpr("chpl__buildSparseDomainRuntimeType", buildDotExpr($actual_expr->copy(), "defaultSparseDist"), $actual_expr); }
| TATOMIC expr { $sub_type_level_expr = new CallExpr("chpl__atomicType", $expr); }
| TSYNC expr { $sub_type_level_expr = new CallExpr( "_syncvar", $expr); }
| TOWNED { $sub_type_level_expr = new UnresolvedSymExpr("_owned"); }
| TOWNED expr { $sub_type_level_expr = new CallExpr( "_owned", $expr); }
| TUNMANAGED { $sub_type_level_expr = new SymExpr(dtUnmanaged->symbol); }
| TUNMANAGED expr { $sub_type_level_expr = new CallExpr( PRIM_TO_UNMANAGED_CLASS_CHECKED, $expr); }
| TSHARED { $sub_type_level_expr = new UnresolvedSymExpr("_shared"); }
| TSHARED expr { $sub_type_level_expr = new CallExpr( "_shared", $expr); }
| TBORROWED { $sub_type_level_expr = new SymExpr(dtBorrowed->symbol); }
| TBORROWED expr { $sub_type_level_expr = new CallExpr( PRIM_TO_BORROWED_CLASS_CHECKED, $expr); }
| TCLASS { $sub_type_level_expr = new SymExpr(dtAnyManagementNonNilable->symbol); }
| TRECORD { $sub_type_level_expr = new SymExpr(dtAnyRecord->symbol); }
;
for_expr:
TFOR expr TIN expr TDO expr %prec TFOR { $for_expr = buildForLoopExpr($2 /* expr_2 */, $4 /* expr_4 */, $6 /* expr_6 */); }
| TFOR expr TIN zippered_iterator TDO expr %prec TFOR { $for_expr = buildForLoopExpr($2 /* expr_2 */, $zippered_iterator, $6 /* expr_6 */, NULL, false, true); }
| TFOR expr TDO expr %prec TFOR { $for_expr = buildForLoopExpr(NULL, $2 /* expr_2 */, $4 /* expr_4 */); }
| TFOR expr TIN expr TDO TIF expr TTHEN expr %prec TNOELSE { $for_expr = buildForLoopExpr($2 /* expr_2 */, $4 /* expr_4 */, $9 /* expr_9 */, $7 /* expr_7 */); }
| TFOR expr TIN zippered_iterator TDO TIF expr TTHEN expr %prec TNOELSE { $for_expr = buildForLoopExpr($2 /* expr_2 */, $zippered_iterator, $9 /* expr_9 */, $7 /* expr_7 */, false, true); }
| TFOR expr TDO TIF expr TTHEN expr %prec TNOELSE { $for_expr = buildForLoopExpr(NULL, $2 /* expr_2 */, $7 /* expr_7 */, $5 /* expr_5 */); }
| TFORALL expr TIN expr TDO expr %prec TFOR { $for_expr = buildForallLoopExpr($2 /* expr_2 */, $4 /* expr_4 */, $6 /* expr_6 */); }
| TFORALL expr TIN zippered_iterator TDO expr %prec TFOR { $for_expr = buildForallLoopExpr($2 /* expr_2 */, $zippered_iterator, $6 /* expr_6 */, NULL, false, true); }
| TFORALL expr TDO expr %prec TFOR { $for_expr = buildForallLoopExpr(NULL, $2 /* expr_2 */, $4 /* expr_4 */); }
| TFORALL expr TIN expr TDO TIF expr TTHEN expr %prec TNOELSE { $for_expr = buildForallLoopExpr($2 /* expr_2 */, $4 /* expr_4 */, $9 /* expr_9 */, $7 /* expr_7 */); }
| TFORALL expr TIN zippered_iterator TDO TIF expr TTHEN expr %prec TNOELSE { $for_expr = buildForallLoopExpr($2 /* expr_2 */, $zippered_iterator, $9 /* expr_9 */, $7 /* expr_7 */, false, true); }
| TFORALL expr TDO TIF expr TTHEN expr %prec TNOELSE { $for_expr = buildForallLoopExpr(NULL, $2 /* expr_2 */, $7 /* expr_7 */, $5 /* expr_5 */); }
| TLSBR expr_ls TRSBR expr %prec TFOR {
if ($expr_ls->argList.length > 1)
$for_expr = buildForallLoopExpr(NULL, new CallExpr("chpl__ensureDomainExpr", $expr_ls), $expr, NULL, true);
else
$for_expr = buildForallLoopExpr(NULL, $expr_ls->get(1)->remove(), $expr, NULL, true);
}
| TLSBR expr_ls TIN expr TRSBR expr %prec TFOR {
if ($expr_ls->argList.length != 1)
USR_FATAL($4 /* expr_4 */, "invalid index expression");
$for_expr = buildForallLoopExpr($expr_ls->get(1)->remove(), $4 /* expr_4 */, $6 /* expr_6 */, NULL, true);
}
| TLSBR expr_ls TIN zippered_iterator TRSBR expr %prec TFOR {
if ($expr_ls->argList.length != 1)
USR_FATAL($zippered_iterator, "invalid index expression");
$for_expr = buildForallLoopExpr($expr_ls->get(1)->remove(), $zippered_iterator, $expr, NULL, false, true);
}
| TLSBR expr_ls TIN expr TRSBR TIF expr TTHEN expr %prec TNOELSE {
if ($expr_ls->argList.length != 1)
USR_FATAL($4 /* expr_4 */, "invalid index expression");
$for_expr = buildForallLoopExpr($expr_ls->get(1)->remove(), $4 /* expr_4 */, $9 /* expr_9 */, $7 /* expr_7 */);
}
| TLSBR expr_ls TIN zippered_iterator TRSBR TIF expr TTHEN expr %prec TNOELSE {
if ($expr_ls->argList.length != 1)
USR_FATAL($zippered_iterator, "invalid index expression");
$for_expr = buildForallLoopExpr($expr_ls->get(1)->remove(), $zippered_iterator, $9 /* expr_9 */, $7 /* expr_7 */, false, true);
}
;
cond_expr:
TIF expr TTHEN expr TELSE expr { $cond_expr = new IfExpr($2 /* expr_2 */, $4 /* expr_4 */, $6 /* expr_6 */); }
/* MPF: it would be nice to match TIF expr TTHEN expr but
the attempt below leads to reduce-reduce conflicts:
TIF expr TTHEN expr %prec TNOELSE
with for_expr.
*/
;
nil_expr:
TNIL { $nil_expr = new SymExpr(gNil); }
;
stmt_level_expr:
nil_expr
| ident_expr
| dot_expr
| call_expr
| lambda_decl_expr
| new_expr
| let_expr
| io_expr TIO expr { $stmt_level_expr = new CallExpr("<~>", $io_expr, $expr); }
;
opt_task_intent_ls:
{ $opt_task_intent_ls = NULL; }
| task_intent_clause
;
task_intent_clause:
TWITH TLP task_intent_ls TRP { $task_intent_clause = $task_intent_ls; }
;
task_intent_ls:
intent_expr { $task_intent_ls = new CallExpr(PRIM_ACTUALS_LIST); addTaskIntent($task_intent_ls, $intent_expr); }
| task_intent_ls[rhs_1] TCOMMA intent_expr { addTaskIntent($rhs_1, $intent_expr); }
;
forall_intent_clause:
TWITH TLP forall_intent_ls TRP { $forall_intent_clause = $forall_intent_ls; }
;
forall_intent_ls:
intent_expr { $forall_intent_ls = new CallExpr(PRIM_ACTUALS_LIST); addForallIntent($forall_intent_ls, $intent_expr); }
| forall_intent_ls[rhs_1] TCOMMA intent_expr { addForallIntent($rhs_1, $intent_expr); }
;
intent_expr:
shadow_var_prefix ident_expr opt_type opt_init_expr {
$intent_expr = ShadowVarSymbol::buildForPrefix($shadow_var_prefix, $ident_expr, $opt_type, $opt_init_expr);
}
| reduce_scan_op_expr TREDUCE ident_expr {
$intent_expr = ShadowVarSymbol::buildFromReduceIntent($ident_expr, $reduce_scan_op_expr);
}
| expr TREDUCE ident_expr {
$intent_expr = ShadowVarSymbol::buildFromReduceIntent($ident_expr, $expr);
}
;
shadow_var_prefix:
TCONST { $shadow_var_prefix = SVP_CONST; }
| TIN { $shadow_var_prefix = SVP_IN; }
| TCONST TIN { $shadow_var_prefix = SVP_CONST_IN; }
| TREF { $shadow_var_prefix = SVP_REF; }
| TCONST TREF { $shadow_var_prefix = SVP_CONST_REF; }
| TVAR { $shadow_var_prefix = SVP_VAR; }
;
io_expr:
lhs_expr
| io_expr[rhs_1] TIO expr { $$ /* io_expr */ = new CallExpr("<~>", $rhs_1, $expr); }
;
new_maybe_decorated:
TNEW %prec TNOELSE { $new_maybe_decorated = new CallExpr(PRIM_NEW); }
| TNEW TOWNED { $new_maybe_decorated = new CallExpr(PRIM_NEW,
new NamedExpr(astr_chpl_manager,
new SymExpr(dtOwned->symbol))); }
| TNEW TSHARED { $new_maybe_decorated = new CallExpr(PRIM_NEW,
new NamedExpr(astr_chpl_manager,
new SymExpr(dtShared->symbol))); }
| TNEW TUNMANAGED { $new_maybe_decorated = new CallExpr(PRIM_NEW,
new NamedExpr(astr_chpl_manager,
new SymExpr(dtUnmanaged->symbol))); }
| TNEW TBORROWED { $new_maybe_decorated = new CallExpr(PRIM_NEW,
new NamedExpr(astr_chpl_manager,
new SymExpr(dtBorrowed->symbol))); }
;
new_expr:
/* handles the typical new cases, e.g. new C(); new owned C() */
new_maybe_decorated expr %prec TNEW { $new_maybe_decorated->insertAtTail($expr);
$new_expr = $new_maybe_decorated; }
/* handles e.g. new (typefn())(initargs) */
| TNEW TOWNED TLP expr TRP TLP opt_actual_ls TRP %prec TNOELSE { $new_expr = new CallExpr(PRIM_NEW,
new NamedExpr(astr_chpl_manager,
new SymExpr(dtOwned->symbol)),
new CallExpr($expr, $opt_actual_ls));
}
| TNEW TSHARED TLP expr TRP TLP opt_actual_ls TRP %prec TNOELSE { $new_expr = new CallExpr(PRIM_NEW,
new NamedExpr(astr_chpl_manager,
new SymExpr(dtShared->symbol)),
new CallExpr($expr, $opt_actual_ls));
}
| TNEW TOWNED TLP expr TRP TLP opt_actual_ls TRP TQUESTION { $new_expr = new CallExpr(PRIM_NEW,
new NamedExpr(astr_chpl_manager,
new SymExpr(dtOwned->symbol)),
new CallExpr(PRIM_TO_NILABLE_CLASS_CHECKED,
new CallExpr($expr, $opt_actual_ls)));
}
| TNEW TSHARED TLP expr TRP TLP opt_actual_ls TRP TQUESTION { $new_expr = new CallExpr(PRIM_NEW,
new NamedExpr(astr_chpl_manager,
new SymExpr(dtShared->symbol)),
new CallExpr(PRIM_TO_NILABLE_CLASS_CHECKED,
new CallExpr($expr, $opt_actual_ls)));
}
;
let_expr:
TLET var_decl_stmt_inner_ls TIN expr { $let_expr = buildLetExpr($var_decl_stmt_inner_ls, $expr); }
;
expr:
literal_expr
| type_level_expr
| for_expr
| reduce_expr
| scan_expr
| lambda_decl_expr
| new_expr
| let_expr
| ifc_constraint
| TLP TDOTDOTDOT expr[rhs_1] TRP { $$ /* expr */ = new CallExpr(PRIM_TUPLE_EXPAND, $rhs_1); }
| expr[rhs_1] TCOLON expr[rhs_2] { $$ /* expr */ = createCast($rhs_1, $rhs_2); }
| expr[rhs_1] TDOTDOT expr[rhs_2] { $$ /* expr */ = buildBoundedRange($rhs_1, $rhs_2); }
| expr[rhs_1] TDOTDOTOPENHIGH expr[rhs_2] { $$ /* expr */ = buildBoundedRange($rhs_1, $rhs_2, false, true); }
/* The following cases would extend the current '..<' open range
interval constructor to also support '<..' and '<..<'. This
concept didn't win enough support to merge as present, but are here
in case we change our minds in a future release.
| expr TDOTDOTOPENLOW expr
{ $$ = buildBoundedRange($1, $3, true, false); }
| expr TDOTDOTOPENBOTH expr
{ $$ = buildBoundedRange($1, $3, true, true); }
| expr TDOTDOTOPENLOW
{ $$ = buildLowBoundedRange($1, true); }
*/
| expr[rhs_1] TDOTDOT { $$ /* expr */ = buildLowBoundedRange($rhs_1); }
| TDOTDOT expr[rhs_1] { $$ /* expr */ = buildHighBoundedRange($rhs_1); }
| TDOTDOTOPENHIGH expr[rhs_1] { $$ /* expr */ = buildHighBoundedRange($rhs_1, true); }
| TDOTDOT { $expr = buildUnboundedRange(); }
;
opt_expr:
{ $opt_expr = NULL; }
| expr { $opt_expr = $expr; }
;
opt_try_expr:
TTRY expr { $opt_try_expr = tryExpr($expr); }
| TTRYBANG expr { $opt_try_expr = tryBangExpr($expr); }
| expr { $opt_try_expr = $expr; }
;
lhs_expr:
ident_expr
| call_expr
| dot_expr
| parenthesized_expr
;
call_base_expr:
lhs_expr { $call_base_expr = $lhs_expr; }
| expr TBANG { $call_base_expr = new CallExpr("postfix!", $expr); }
| sub_type_level_expr TQUESTION {$call_base_expr = new CallExpr(PRIM_TO_NILABLE_CLASS_CHECKED, $sub_type_level_expr);}
| lambda_decl_expr { $call_base_expr = $lambda_decl_expr; }
| str_bytes_literal
;
call_expr:
call_base_expr TLP opt_actual_ls TRP { $call_expr = new CallExpr($call_base_expr, $opt_actual_ls); }
| call_base_expr TLSBR opt_actual_ls TRSBR { $call_expr = buildSquareCallExpr($call_base_expr, $opt_actual_ls); }
| TPRIMITIVE TLP opt_actual_ls TRP { $call_expr = buildPrimitiveExpr($opt_actual_ls); }
;
dot_expr:
expr TDOT ident_use { $dot_expr = buildDotExpr($expr, $ident_use); }
| expr TDOT TTYPE { $dot_expr = new CallExpr(PRIM_TYPEOF, $expr); }
| expr TDOT TDOMAIN { $dot_expr = buildDotExpr($expr, "_dom"); }
| expr TDOT TLOCALE { $dot_expr = buildDotExpr($expr, "locale"); }
| expr TDOT TBYTES TLP TRP { $dot_expr = new CallExpr(buildDotExpr($expr, "chpl_bytes")); }
;
parenthesized_expr:
TLP tuple_component TRP { $parenthesized_expr = $tuple_component; }
| TLP tuple_component TCOMMA TRP { $parenthesized_expr = buildOneTuple($tuple_component); }
| TLP tuple_expr_ls TRP { $parenthesized_expr = buildTuple($tuple_expr_ls); }
| TLP tuple_expr_ls TCOMMA TRP { $parenthesized_expr = buildTuple($tuple_expr_ls); }
;
bool_literal:
TFALSE { $bool_literal = new SymExpr(gFalse); }
| TTRUE { $bool_literal = new SymExpr(gTrue); }
;
str_bytes_literal:
STRINGLITERAL { $str_bytes_literal = buildStringLiteral($STRINGLITERAL); }
| BYTESLITERAL { $str_bytes_literal = buildBytesLiteral($BYTESLITERAL); }
;
literal_expr:
bool_literal
| str_bytes_literal
| INTLITERAL { $literal_expr = buildIntLiteral($INTLITERAL, yyfilename, chplLineno); }
| REALLITERAL { $literal_expr = buildRealLiteral($REALLITERAL); }
| IMAGLITERAL { $literal_expr = buildImagLiteral($IMAGLITERAL); }
| CSTRINGLITERAL { $literal_expr = buildCStringLiteral($CSTRINGLITERAL); }
| TNONE { $literal_expr = new SymExpr(gNone); }
| TLCBR expr_ls TRCBR { $literal_expr = new CallExpr("chpl__buildDomainExpr", $expr_ls,
new SymExpr(gTrue)); }
| TLCBR expr_ls TCOMMA TRCBR { $literal_expr = new CallExpr("chpl__buildDomainExpr", $expr_ls,
new SymExpr(gTrue)); }
| TLSBR expr_ls TRSBR { $literal_expr = new CallExpr("chpl__buildArrayExpr", $expr_ls); }
| TLSBR expr_ls TCOMMA TRSBR { $literal_expr = new CallExpr("chpl__buildArrayExpr", $expr_ls); }
| TLSBR assoc_expr_ls TRSBR {
$literal_expr = new CallExpr("chpl__buildAssociativeArrayExpr", $assoc_expr_ls);
}
| TLSBR assoc_expr_ls TCOMMA TRSBR {
$literal_expr = new CallExpr("chpl__buildAssociativeArrayExpr", $assoc_expr_ls);
}
;
assoc_expr_ls:
expr TALIAS expr { $assoc_expr_ls = new CallExpr(PRIM_ACTUALS_LIST, $1 /* expr_1 */, $3 /* expr_3 */); }
| assoc_expr_ls[rhs_1] TCOMMA expr TALIAS expr { $rhs_1->insertAtTail($3 /* expr_3 */); $rhs_1->insertAtTail($5 /* expr_5 */); }
;
binary_op_expr:
expr TPLUS expr { $binary_op_expr = new CallExpr("+", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TMINUS expr { $binary_op_expr = new CallExpr("-", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TSTAR expr { $binary_op_expr = new CallExpr("*", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TDIVIDE expr { $binary_op_expr = new CallExpr("/", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TSHIFTLEFT expr { $binary_op_expr = new CallExpr("<<", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TSHIFTRIGHT expr { $binary_op_expr = new CallExpr(">>", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TMOD expr { $binary_op_expr = new CallExpr("%", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TEQUAL expr { $binary_op_expr = new CallExpr("==", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TNOTEQUAL expr { $binary_op_expr = new CallExpr("!=", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TLESSEQUAL expr { $binary_op_expr = new CallExpr("<=", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TGREATEREQUAL expr { $binary_op_expr = new CallExpr(">=", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TLESS expr { $binary_op_expr = new CallExpr("<", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TGREATER expr { $binary_op_expr = new CallExpr(">", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TBAND expr { $binary_op_expr = new CallExpr("&", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TBOR expr { $binary_op_expr = new CallExpr("|", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TBXOR expr { $binary_op_expr = new CallExpr("^", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TAND expr { $binary_op_expr = new CallExpr("&&", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TOR expr { $binary_op_expr = new CallExpr("||", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TEXP expr { $binary_op_expr = new CallExpr("**", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TBY expr { $binary_op_expr = new CallExpr("chpl_by", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TALIGN expr { $binary_op_expr = new CallExpr("chpl_align", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr THASH expr { $binary_op_expr = new CallExpr("#", $1 /* expr_1 */, $3 /* expr_3 */); }
| expr TDMAPPED expr { $binary_op_expr = new CallExpr("chpl__distributed", $3 /* expr_3 */, $1 /* expr_1 */,
new SymExpr(gTrue)); }
;
unary_op_expr:
TPLUS expr %prec TUPLUS { $unary_op_expr = new CallExpr("+", $expr); }
| TMINUS expr %prec TUMINUS { $unary_op_expr = new CallExpr("-", $expr); }
| TMINUSMINUS expr %prec TUMINUS { $unary_op_expr = buildPreDecIncWarning($expr, '-'); }
| TPLUSPLUS expr %prec TUPLUS { $unary_op_expr = buildPreDecIncWarning($expr, '+'); }
| TBANG expr %prec TLNOT { $unary_op_expr = new CallExpr("!", $expr); }
| expr TBANG { $unary_op_expr = new CallExpr("postfix!", $expr); }
| TBNOT expr { $unary_op_expr = new CallExpr("~", $expr); }
;
reduce_expr:
expr TREDUCE expr { $reduce_expr = buildReduceExpr($1 /* expr_1 */, $3 /* expr_3 */); }
| expr TREDUCE zippered_iterator { $reduce_expr = buildReduceExpr($expr, $zippered_iterator, true); }
| reduce_scan_op_expr TREDUCE expr { $reduce_expr = buildReduceExpr($reduce_scan_op_expr, $expr); }
| reduce_scan_op_expr TREDUCE zippered_iterator { $reduce_expr = buildReduceExpr($reduce_scan_op_expr, $zippered_iterator, true); }
;
scan_expr:
expr TSCAN expr { $scan_expr = buildScanExpr($1 /* expr_1 */, $3 /* expr_3 */); }
| expr TSCAN zippered_iterator { $scan_expr = buildScanExpr($expr, $zippered_iterator, true); }
| reduce_scan_op_expr TSCAN expr { $scan_expr = buildScanExpr($reduce_scan_op_expr, $expr); }
| reduce_scan_op_expr TSCAN zippered_iterator { $scan_expr = buildScanExpr($reduce_scan_op_expr, $zippered_iterator, true); }
;
reduce_scan_op_expr:
TPLUS { $reduce_scan_op_expr = new UnresolvedSymExpr("SumReduceScanOp"); }
| TSTAR { $reduce_scan_op_expr = new UnresolvedSymExpr("ProductReduceScanOp"); }
| TAND { $reduce_scan_op_expr = new UnresolvedSymExpr("LogicalAndReduceScanOp"); }
| TOR { $reduce_scan_op_expr = new UnresolvedSymExpr("LogicalOrReduceScanOp"); }
| TBAND { $reduce_scan_op_expr = new UnresolvedSymExpr("BitwiseAndReduceScanOp"); }
| TBOR { $reduce_scan_op_expr = new UnresolvedSymExpr("BitwiseOrReduceScanOp"); }
| TBXOR { $reduce_scan_op_expr = new UnresolvedSymExpr("BitwiseXorReduceScanOp"); }
;
I'm working to achieve a LALR(1)/LEX to try grammars online with wasm based on https://github.com/BenHanson/gram_grep and I've got the Chappel
grammar working, view it here https://mingodad.github.io/parsertl-playground/playground/ select Chappel parser
from the examples, you can edit the Grammar or the Input source and press Parse to see a parser tree.
I hope it can be a nice tool to experiment with LALR(1)/LEX grammars with instant feedback !
Using this tool https://www.bottlecaps.de/convert/ and manually adding the tokens from
main/compiler/parser/chapel.lex
we can see a railroad diagram for the grammar inmain/compiler/parser/chapel.ypp
copy and paste the EBNF shown bellow on https://www.bottlecaps.de/rr/ui in the tab Edit Grammar then switching to the tab View Diagram.