miller/cmd/experiments/dsl_parser/two/temp.bnf
2022-01-23 23:22:55 -05:00

219 lines
4.7 KiB
BNF

// ================================================================
// LEXER
!whitespace : ' ' | '\t' | '\n' | '\r' ;
!comment : '#' {.} '\n' ;
_letter : 'a'-'z' | 'A'-'Z' ;
_decdig : '0'-'9' ;
_idchar : _letter | _decdig | '_' ;
emitf : 'e' 'm' 'i' 't' 'f';
emit : 'e' 'm' 'i' 't' ;
stdout : 's' 't' 'd' 'o' 'u' 't' ;
stderr : 's' 't' 'd' 'e' 'r' 'r' ;
// ================================================================
// IMPORT
<< import "two/src/dsl" >>
// ================================================================
// PARSER
// ----------------------------------------------------------------
Root
: EmitFStatement
<< dsl.NewAST($0) >>
| EmitStatement
<< dsl.NewAST($0) >>
;
// ----------------------------------------------------------------
Redirector
: ">" RedirectTarget
<< dsl.NewASTNodeUnary($0, $1, dsl.NodeTypeRedirectWrite) >>
| ">>" RedirectTarget
<< dsl.NewASTNodeUnary($0, $1, dsl.NodeTypeRedirectAppend) >>
| "|" RedirectTarget
<< dsl.NewASTNodeUnary($0, $1, dsl.NodeTypeRedirectPipe) >>
;
RedirectTarget
: stdout
<< dsl.NewASTNodeZary($0, dsl.NodeTypeRedirectTargetStdout) >>
| stderr
<< dsl.NewASTNodeZary($0, dsl.NodeTypeRedirectTargetStderr) >>
| Rvalue
;
// ----------------------------------------------------------------
EmitStatement
: emit Emittable
<<
dsl.NewASTNodeTernary(
$0,
$1,
dsl.NewASTNodeNestable(nil, dsl.NodeTypeNoOp),
dsl.NewASTNodeNestable(nil, dsl.NodeTypeNoOp),
dsl.NodeTypeEmitStatement,
)
>>
| emit Redirector "," Emittable
<<
dsl.NewASTNodeTernary(
$0,
$3,
dsl.NewASTNodeNestable(nil, dsl.NodeTypeNoOp),
$1,
dsl.NodeTypeEmitStatement,
)
>>
| emit "(" EmittableList ")"
<<
dsl.NewASTNodeTernary(
$0,
$2,
dsl.NewASTNodeNestable(nil, dsl.NodeTypeNoOp),
dsl.NewASTNodeNestable(nil, dsl.NodeTypeNoOp),
dsl.NodeTypeEmitStatement,
)
>>
| emit Redirector "," "(" EmittableList ")"
<<
dsl.NewASTNodeTernary(
$0,
$4,
dsl.NewASTNodeNestable(nil, dsl.NodeTypeNoOp),
$1,
dsl.NodeTypeEmitStatement,
)
>>
| emit Emittable "," EmitKeys
<<
dsl.NewASTNodeTernary(
$0,
$1,
$3,
dsl.NewASTNodeNestable(nil, dsl.NodeTypeNoOp),
dsl.NodeTypeEmitStatement,
)
>>
| emit Redirector "," Emittable "," EmitKeys
<<
dsl.NewASTNodeTernary(
$0,
$3,
$5,
$1,
dsl.NodeTypeEmitStatement,
)
>>
| emit "(" EmittableList ")" "," EmitKeys
<<
dsl.NewASTNodeTernary(
$0,
$2,
$5,
dsl.NewASTNodeNestable(nil, dsl.NodeTypeNoOp),
dsl.NodeTypeEmitStatement,
)
>>
| emit Redirector "," "(" EmittableList ")" "," EmitKeys
<<
dsl.NewASTNodeTernary(
$0,
$4,
$7,
$1,
dsl.NodeTypeEmitStatement,
)
>>
;
// ----------------------------------------------------------------
// Examples:
// emitf @a
// emitf @a, b, $c
// Each argument must be a non-indexed oosvar/localvar/fieldname, so we can use
// their names as keys in the emitted record.
EmitFStatement
: emitf EmittableList
<< dsl.AdoptChildren(
dsl.NewASTNodeNestable(
$0,
dsl.NodeTypeEmitFStatement,
),
$1,
) >>
| emitf Redirector "," EmittableList
// TODO
;
// ----------------------------------------------------------------
EmittableList
: Emittable
<< dsl.NewASTNodeUnary(
nil,
$0,
dsl.NodeTypeEmittableList,
) >>
// Allow trailing final comma, especially for multiline statements
| Emittable "," EmittableList
<< dsl.PrependChild(
$2,
$0,
) >>
;
Emittable
: Literal
;
// ----------------------------------------------------------------
EmitKeys
: Rvalue
<< dsl.NewASTNodeUnary(
nil,
$0,
dsl.NodeTypeEmitKeys,
) >>
| Rvalue "," EmitKeys
<< dsl.PrependChild(
$2,
$0,
) >>
;
// ----------------------------------------------------------------
Rvalue
: Literal
<< dsl.NewASTNodeUnary(nil, $0, dsl.NodeTypeStringLiteral) >>
| "(" Literal ")"
<< dsl.NewASTNodeUnary(nil, $1, dsl.NodeTypeStringLiteral) >>
| "[" Literal "]"
<< dsl.NewASTNodeUnary(nil, $1, dsl.NodeTypeStringLiteral) >>
| "[" Literal "," Literal "]"
<< dsl.NewASTNodeBinary(nil, $1, $2, dsl.NodeTypeStringLiteral) >>
;
Literal
: "x" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >>
| "y" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >>
| "z" << dsl.NewASTNodeZary($0, dsl.NodeTypeStringLiteral) >>
;