Server IP : 85.214.239.14 / Your IP : 3.129.210.35 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/self/root/usr/share/doc/re2c/examples/go/state/ |
Upload File : |
// Code generated by re2c, DO NOT EDIT. //line "go/state/push.re":1 //go:generate re2go -f $INPUT -o $OUTPUT package main import ( "fmt" "os" ) // Use a small buffer to cover the case when a lexeme doesn't fit. // In real world use a larger buffer. const BUFSIZE int = 10 type State struct { file *os.File buf []byte cur int mar int tok int lim int state int } const ( lexEnd = iota lexReady lexWaitingForInput lexPacketBroken lexPacketTooBig ) func fill(st *State) int { shift := st.tok used := st.lim - st.tok free := BUFSIZE - used // Error: no space. In real life can reallocate a larger buffer. if free < 1 { return lexPacketTooBig } // Shift buffer contents (discard already processed data). copy(st.buf[0:], st.buf[shift:shift+used]) st.cur -= shift st.mar -= shift st.lim -= shift st.tok -= shift // Fill free space at the end of buffer with new data. n, _ := st.file.Read(st.buf[st.lim:BUFSIZE]) st.lim += n st.buf[st.lim] = 0 // append sentinel symbol return lexReady } func lex(st *State, recv *int) int { var yych byte //line "go/state/push.go":60 switch (st.state) { default: goto yy0 case 0: if (st.lim <= st.cur) { goto yy8 } goto yyFillLabel0 case 1: if (st.lim <= st.cur) { goto yy3 } goto yyFillLabel1 case 2: if (st.lim <= st.cur) { goto yy7 } goto yyFillLabel2 } //line "go/state/push.re":56 loop: st.tok = st.cur //line "go/state/push.go":85 yy0: yyFillLabel0: yych = st.buf[st.cur] switch (yych) { case 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z': goto yy4 default: if (st.lim <= st.cur) { st.state = 0 return lexWaitingForInput } goto yy2 } yy2: st.cur += 1 yy3: st.state = -1 //line "go/state/push.re":72 { return lexPacketBroken } //line "go/state/push.go":106 yy4: st.cur += 1 st.mar = st.cur yyFillLabel1: yych = st.buf[st.cur] switch (yych) { case ';': goto yy5 case 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z': goto yy6 default: if (st.lim <= st.cur) { st.state = 1 return lexWaitingForInput } goto yy3 } yy5: st.cur += 1 st.state = -1 //line "go/state/push.re":74 { *recv = *recv + 1; goto loop } //line "go/state/push.go":129 yy6: st.cur += 1 yyFillLabel2: yych = st.buf[st.cur] switch (yych) { case ';': goto yy5 case 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z': goto yy6 default: if (st.lim <= st.cur) { st.state = 2 return lexWaitingForInput } goto yy7 } yy7: st.cur = st.mar goto yy3 yy8: st.state = -1 //line "go/state/push.re":73 { return lexEnd } //line "go/state/push.go":153 //line "go/state/push.re":75 } func test(expect int, packets []string) { // Create a "socket" (open the same file for reading and writing). fname := "pipe" fw, _ := os.Create(fname) fr, _ := os.Open(fname) // Initialize lexer state: `state` value is -1, all offsets are at the end // of buffer. st := &State{ file: fr, // Sentinel at `lim` offset is set to zero, which triggers YYFILL. buf: make([]byte, BUFSIZE+1), cur: BUFSIZE, mar: BUFSIZE, tok: BUFSIZE, lim: BUFSIZE, state: -1, } // Main loop. The buffer contains incomplete data which appears packet by // packet. When the lexer needs more input it saves its internal state and // returns to the caller which should provide more input and resume lexing. var status int send := 0 recv := 0 for { status = lex(st, &recv) if status == lexEnd { break } else if status == lexWaitingForInput { if send < len(packets) { fw.WriteString(packets[send]) send += 1 } status = fill(st) if status != lexReady { break } } else if status == lexPacketBroken { break } } // Check results. if status != expect || (status == lexEnd && recv != send) { panic(fmt.Sprintf("got %d, want %d", status, expect)) } // Cleanup: remove input file. fr.Close() fw.Close() os.Remove(fname) } func main() { test(lexEnd, []string{}) test(lexEnd, []string{"zero;", "one;", "two;", "three;", "four;"}) test(lexPacketBroken, []string{"??;"}) test(lexPacketTooBig, []string{"looooooooooooong;"}) }