miller/cmd/experiments/dsl_parser/two/temp.bnf
John Kerl ced5e43065
Simplify the internal AST API (#1946)
* Simplify the internal AST API

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating

* iterating, bisecting

* mlr.bnf neatens

* update old/experimental .bnf files

* More AST method-name changes
2026-02-01 15:15:49 -05:00

302 lines
5.6 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.NewASTWithErrorReturn($0) >>
| EmitStatement
<< dsl.NewASTWithErrorReturn($0) >>
;
// ----------------------------------------------------------------
Redirector
: ">" RedirectTarget
<< dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeRedirectWrite,
[]interface{}{
$1,
}
) >>
| ">>" RedirectTarget
<< dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeRedirectAppend,
[]interface{}{
$1,
}
) >>
| "|" RedirectTarget
<< dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeRedirectPipe,
[]interface{}{
$1,
}
) >>
;
RedirectTarget
: stdout
<< dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeRedirectTargetStdout,
[]interface{}{}
) >>
| stderr
<< dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeRedirectTargetStderr,
[]interface{}{}
) >>
| Rvalue
;
// ----------------------------------------------------------------
EmitStatement
: emit Emittable
<<
dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeEmitStatement,
[]interface{}{
$1,
dsl.NewASTNodeTerminal(nil, dsl.NodeTypeNoOp),
dsl.NewASTNodeTerminal(nil, dsl.NodeTypeNoOp),
}
))
>>
| emit Redirector "," Emittable
<<
dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeEmitStatement,
[]interface{}{
$3,
dsl.NewASTNodeTerminal(nil, dsl.NodeTypeNoOp),
$1,
}
))
>>
| emit "(" EmittableList ")"
<<
dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeEmitStatement,
[]interface{}{
$2,
dsl.NewASTNodeTerminal(nil, dsl.NodeTypeNoOp),
dsl.NewASTNodeTerminal(nil, dsl.NodeTypeNoOp),
}
))
>>
| emit Redirector "," "(" EmittableList ")"
<<
dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeEmitStatement,
[]interface{}{
$4,
dsl.NewASTNodeTerminal(nil, dsl.NodeTypeNoOp),
$1,
}
))
>>
| emit Emittable "," EmitKeys
<<
dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeEmitStatement,
[]interface{}{
$1,
$3,
dsl.NewASTNodeTerminal(nil, dsl.NodeTypeNoOp),
}
))
>>
| emit Redirector "," Emittable "," EmitKeys
<<
dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeEmitStatement,
[]interface{}{
$3,
$5,
$1,
}
))
>>
| emit "(" EmittableList ")" "," EmitKeys
<<
dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeEmitStatement,
[]interface{}{
$2,
$5,
dsl.NewASTNodeTerminal(nil, dsl.NodeTypeNoOp),
}
))
>>
| emit Redirector "," "(" EmittableList ")" "," EmitKeys
<<
dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeEmitStatement,
[]interface{}{
$4,
$7,
$1,
}
))
>>
;
// ----------------------------------------------------------------
// 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.WithChildrenAdopted(
dsl.NewASTNodeTerminal(
$0,
dsl.NodeTypeEmitFStatement,
),
$1,
) >>
| emitf Redirector "," EmittableList
// TODO
;
// ----------------------------------------------------------------
EmittableList
: Emittable
<< dsl.NewASTNodeWithErrorReturn(
nil,
dsl.NodeTypeEmittableList,
[]interface{}{
$0,
}
) >>
// Allow trailing final comma, especially for multiline statements
| Emittable "," EmittableList
<< dsl.WithChildPrepended(
$2,
$0,
) >>
;
Emittable
: Literal
;
// ----------------------------------------------------------------
EmitKeys
: Rvalue
<< dsl.NewASTNodeWithErrorReturn(
nil,
dsl.NodeTypeEmitKeys,
[]interface{}{
$0,
}
) >>
| Rvalue "," EmitKeys
<< dsl.WithChildPrepended(
$2,
$0,
) >>
;
// ----------------------------------------------------------------
Rvalue
: Literal
<< dsl.NewASTNodeWithErrorReturn(
nil,
dsl.NodeTypeStringLiteral,
[]interface{}{
$0,
}
) >>
| "(" Literal ")"
<< dsl.NewASTNodeWithErrorReturn(
nil,
dsl.NodeTypeStringLiteral,
[]interface{}{
$1,
}
) >>
| "[" Literal "]"
<< dsl.NewASTNodeWithErrorReturn(
nil,
dsl.NodeTypeStringLiteral,
[]interface{}{
$1,
}
) >>
| "[" Literal "," Literal "]"
<< dsl.NewASTNodeWithErrorReturn(
nil,
dsl.NodeTypeStringLiteral,
[]interface{}{
$1,
$2,
}
) >>
;
Literal
: "x" << dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeStringLiteral,
[]interface{}{}
) >>
| "y" << dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeStringLiteral,
[]interface{}{}
) >>
| "z" << dsl.NewASTNodeWithErrorReturn(
$0,
dsl.NodeTypeStringLiteral,
[]interface{}{}
) >>
;