Lark EBNF grammar for a Data Flow assembly graph language
Something went wrong. Try again.
or1-dfasm
· Created 7mo ago ·4.4 kB · 143 lines
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144// Dataflow Graph Assembly — Lark EBNF Grammar v0.2// Parser: Earley (required for ambiguity-free resolution of location_dir vs weak_edge)start: (_NL* statement)* _NL*?statement: func_def | inst_def | strong_edge | weak_edge | plain_edge | data_def | location_dir// --- Function / subgraph definition ---// $name |> { body }func_def: func_ref FLOW_OUT "{" (_NL* statement)* _NL* "}"// --- Instruction definition (named node) ---// &label <| opcode [, arg ...]inst_def: qualified_ref FLOW_IN opcode ("," argument)*// --- Strong inline edge (internal route, anonymous node) ---// opcode input [, input ...] |> output [, output ...]strong_edge: opcode argument ("," argument)* FLOW_OUT ref_list// --- Weak inline edge (token output, anonymous node) ---// output [, output ...] opcode <| input [, input ...]weak_edge: ref_list opcode FLOW_IN argument ("," argument)*// --- Plain edge (wiring between named nodes) ---// source |> dest [, dest ...]plain_edge: qualified_ref FLOW_OUT ref_list// --- Data / initialisation ---// ref = value | ref = #macro argsdata_def: qualified_ref "=" (macro_call | value_list)// --- Location directive (bare qualified ref, no operator) ---// Sets location context for subsequent definitions.location_dir: qualified_ref// === Shared productions ===ref_list: qualified_ref ("," qualified_ref)*// === References ===// Qualifier chain: max one placement (|ident) and one port (:spec).// @name — node reference// &name — local label reference// $name — function / subgraph reference// Chaining: @sum|pe0:L (placement + port)qualified_ref: (node_ref | label_ref | func_ref) placement? port?node_ref: "@" IDENTlabel_ref: "&" IDENTfunc_ref: "$" IDENTplacement: "|" IDENTport: ":" PORT_SPECPORT_SPEC: IDENT | HEX_LIT | DEC_LIT// === Arguments ===// An argument is a value, a qualified ref, or a named key=value pair.// Named args are syntactically valid on any instruction.// Semantic validation (which ops accept named args) is deferred to the assembler.?argument: named_arg | positional_argnamed_arg: IDENT "=" positional_arg?positional_arg: value | qualified_ref// === Values (literals) ===?value: HEX_LIT -> hex_literal | DEC_LIT -> dec_literal | CHAR_LIT -> char_literal | STRING_LIT -> string_literal | RAW_STRING_LIT -> raw_string_literal | BYTE_STRING_LIT -> byte_string_literalvalue_list: value ("," value)*// === Macros ===// #name arg [arg ...] — expanded in a later pass, not during parsing.macro_call: "#" IDENT (value | qualified_ref)*// === Opcodes ===// Exhaustive keyword terminal. Priority 2 ensures opcodes win over IDENT// at the lexer level. Semantic validation (monadic/dyadic arity, valid// argument combinations) is deferred to the assembler.opcode: OPCODEOPCODE.2: "add" | "sub" | "inc" | "dec" | "shiftl" | "shiftr" | "ashiftr" | "and" | "or" | "xor" | "not" | "eq" | "lt" | "lte" | "gt" | "gte" | "breq" | "brgt" | "brge" | "brof" | "brty" | "sweq" | "swgt" | "swge" | "swof" | "swty" | "gate" | "sel" | "merge" | "pass" | "const" | "free" | "ior" | "iow" | "iorw" | "load_inst" | "route_set"// === Flow operators ===// Priority 3 to win over any partial match of | or < or >FLOW_IN.3: "<|"FLOW_OUT.3: "|>"// === Terminals ===HEX_LIT: /0x[0-9a-fA-F]+/DEC_LIT: /[0-9]+/// Character literals: single char or escape sequence.// Supported escapes: \n \t \r \0 \\ \' \xNNCHAR_LIT: /'([^'\\]|\\[ntr0\\']|\\x[0-9a-fA-F]{2})'/// String literals — Rust-style semantics.// "..." regular string, escape sequences processed by assembler// r"..." raw string, no escape processing// b"..." byte string, semantic difference only (raw byte values)// Multi-line strings are permitted: /s flag makes . match \n.STRING_LIT: /\"([^\"\\]|\\.)*\"/sRAW_STRING_LIT: /r\"[^\"]*\"/sBYTE_STRING_LIT: /b\"([^\"\\]|\\.)*\"/sIDENT: /[a-zA-Z_][a-zA-Z0-9_]*/// === Whitespace & Comments ===// ; starts a comment to end of line (traditional asm behaviour).// Newlines are significant as statement separators.COMMENT: /;[^\n]*/_NL: (NEWLINE | COMMENT) (NEWLINE | COMMENT)*%import common.NEWLINE%import common.WS_INLINE%ignore WS_INLINE%ignore COMMENT