## 2025-02-06 grammar grammar # # comment # =| 'literal' ; # 'l' or 'i' or 't' or 'e' or 'r' or 'a' # = # | 'abc' # choice 0 : 'a' or 'b' or 'c' # | 'x' 'y' 'z' # choice 1 : 'x' then 'y' then 'z' # ; # # maybe quotes for sequential strings ? # =| 'a'? ; # <_one_or_more> =| 'b'+ ; # =| 'c'* ; #### # grammar grammar =| <_> * ; <_> =| * ; =| ' ' | '\t' | '\n' | '\r' | ; =| '#' * '\n' ; # any single printing ascii character other than newline = # alphanum | 'abcdefghijklmnopqrstuvwxyz' | 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' | '0123456789' # whitespace | ' \t' # '\n\r' # symbols | '`~!@#$%^&*()-_=+' | '[{]}\\|' | ';:' | '\'' | '"' | ',<.>/?' ; =| '=' <_> + ';' <_> ; =| '<' * '>' <_> ; = | 'abcdefghijklmnopqrstuvwxyz' | 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' ; = | 'abcdefghijklmnopqrstuvwxyz' | 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' | '0123456789' ; =| '|' <_> * ; =| ? <_> ; = | | ; =| '\'' + '\'' ; = | '\\' | ; # - tab, (newline), backslash, and apostrophe = # alphanum | 'abcdefghijklmnopqrstuvwxyz' | 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' | '0123456789' # whitespace | ' ' # '\t\n\r' # symbols | '`~!@#$%^&*()-_=+' | '[{]}|' # '\\' | ';:' | '"' # '\'' | ',<.>/?' ; =| '?' | '+' | '*' ; ##### # #const AL = std.ArrayList; # #/// =| <_> * ; #const grammar = struct { @0 :_, @1 :AL( assignment ), }; #/// <_> =| * ; #const _ = struct { @0 :AL( whitespace ), }; #/// =| ' ' | '\t' | '\n' | '\r' | ; #const whitespace = union { @" " :u32, @"\t" :u32, @"\n" :u32, @"\r" :u32, }; #/// =| '#' * '\n' ; #const comment = struct { @0 :u32, @1 :AL( dot ), @2 :u32, }; #/// # any single printing ascii character other than newline #const dot = struct { @0 :u32 }; // XXX heck this #/// =| '=' <_> + ';' <_> ; #const assignment = struct { @0 :identifier, @1 :u32, @2 :_, @3 :AL( rule ), @4 :u32, @5 :_, }; #/// =| '<' * '>' <_> ; #const identifier = struct { @0 :u32, @1 :alpha, @2 :AL( alphanum ), @3 :u32, @4 :_, }; #/// = #/// | 'abcdefghijklmnopqrstuvwxyz' #/// | 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' #/// ; #const alpha = struct { @0 :u32 }; // XXX heck this #/// = #/// | 'abcdefghijklmnopqrstuvwxyz' #/// | 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' #/// | '0123456789' #/// ; #const alphanum = struct { @0 :u32 }; // XXX heck this #/// =| '|' <_> * ; #const rule = struct { @0 :u32, @1 :_, @2 :AL( term ), }; #/// =| ? <_> ; #const term = struct { @0 :atom, @1 :?suffix, @2 :_, }; #/// = #/// | #/// | #/// ; #const atom = union { @0 :identifier, @1 :LITERAL, }; #/// =| '\'' + '\'' ; #const LITERAL = struct { @0 :u32, @1 :AL( inner ), @2 :u32, }; #/// = #/// | '\\' #/// | #/// ; #const inner = union { @0 :struct { @0 :u32, @1 :dot, }, @1 :plain, }; #/// # - tab, (newline), backslash, and apostrophe #const plain = struct { @0 :u32 }; // XXX heck this #/// =| '?' | '+' | '*' ; #const suffix = union { @0 :u32, @1 :u32, @2 :u32, }; # # # #const state = union { # grammar, # _, # whitespace, # comment, # dot, # assignment, # identifier, # rule, # term, # atom, # LITERAL, # inner, # plain, # suffix, #}; # #const Tokenizer = struct { # stack :ArrayList( *state ), # src :[]const u8, # i :u32, #}; # #fn next( t :*Tokenizer ) u32 { # while( t.i < t.src.len ) { # var next_token = t.src[ t.i ]; # switch( t.stack.top().* ) { # case( .grammar ) |x| { switch( next_token ) { # // case( '#' ) { stack.push( .comment ); i += 1; continue; }, # case( '#', ' ', '\t', '\n', '\r' ) { stack.push( &x.0 ); continue; } # case( '<' ) |x| { t.stack.push( &x.@1 ); }, # else { return error.unrecognized; }, # } }, # case( .whitespace ) { switch( next_token ) { # case( ' ', '\t', '\n', '\r' ) { i += 1; continue; }, # case( '#' ) { stack.push( .comment ); continue; }, # else { stack.pop(); }, # } }, # case( .comment ) { switch( next_token ) { # case( '\n' ) { stack.pop(); i += 1; return i; }, # else { i += 1; } # } }, # case( .identifier ) { TODO }, # case( .assignment ) { TODO }, # case( .identifier ) { TODO }, # case( .identifier ) { TODO }, # case( .identifier ) { TODO }, # case( .identifier ) { TODO }, # case( .identifier ) { TODO }, # case( .identifier ) { TODO }, # case( .identifier ) { TODO }, # case( .identifier ) { TODO }, # # case( .grammar ) { TODO }, # case( ._ ) { TODO }, # case( .whitespace ) { TODO }, # case( .comment ) { TODO }, # case( .dot ) { TODO }, # case( .assignment ) { TODO }, # case( .identifier ) { TODO }, # case( .rule ) { TODO }, # case( .term ) { TODO }, # case( .atom ) { TODO }, # case( .LITERAL ) { TODO }, # case( .inner ) { TODO }, # case( .plain ) { TODO }, # case( .suffix ) { TODO }, # # } # } # return index; #} # #Tokenizer = struct { # stack :ArrayList( state ) # src :[]const u8 # i :u32 # # next( self :*Tokenizer ) u32 { # # } # # type( offset ) #} # #enum { # '#' // comment # '\n' // newline # '<' // rule identifier start # '>' // rule identifier end # '=' // assignment # ';' # '|' // prefix to rule # '?' // zero-or-one # '+' // one-or-more # '*' // zero-or-more # '\'' // any-of union # '"' // literal # '\\' // escape #} # # # #// XXX pan lang #variant { # .character // not single char identifiers # .identifier // includes keywords # .comment # .string // "..." # .line_string // `"...\n` or `/"...\n` # .number // 0 or 0.0 or 0.0p10 # // sign in number literals ? # .whitespace #}