%PDF- %PDF-
| Direktori : /usr/share/doc/re2c/examples/go/fill/ |
| Current File : //usr/share/doc/re2c/examples/go/fill/01_fill.go |
// Code generated by re2c, DO NOT EDIT.
//line "go/fill/01_fill.re":1
//go:generate re2go $INPUT -o $OUTPUT
package main
import (
"os"
"strings"
)
const BUFSIZE int = 4096
type Input struct {
file *os.File
buf []byte
cur int
mar int
tok int
lim int
eof bool
}
func fill(in *Input) int {
if in.eof { return -1 } // unexpected EOF
// Error: lexeme too long. In real life can reallocate a larger buffer.
if in.tok < 1 { return -2 }
// Shift buffer contents (discard everything up to the current token).
copy(in.buf[0:], in.buf[in.tok:in.lim])
in.cur -= in.tok
in.mar -= in.tok
in.lim -= in.tok
in.tok = 0
// Fill free space at the end of buffer with new data from file.
n, _ := in.file.Read(in.buf[in.lim:BUFSIZE])
in.lim += n
in.buf[in.lim] = 0
// If read less than expected, this is the end of input.
in.eof = in.lim < BUFSIZE
return 0
}
func lex(in *Input) int {
count := 0
for {
in.tok = in.cur
//line "go/fill/01_fill.go":53
{
var yych byte
yyFillLabel0:
yych = in.buf[in.cur]
switch (yych) {
case ' ':
goto yy3
case '\'':
goto yy5
default:
if (in.lim <= in.cur) {
if (fill(in) == 0) {
goto yyFillLabel0
}
goto yy10
}
goto yy1
}
yy1:
in.cur += 1
yy2:
//line "go/fill/01_fill.re":61
{ return -1 }
//line "go/fill/01_fill.go":77
yy3:
in.cur += 1
yyFillLabel1:
yych = in.buf[in.cur]
switch (yych) {
case ' ':
goto yy3
default:
if (in.lim <= in.cur) {
if (fill(in) == 0) {
goto yyFillLabel1
}
}
goto yy4
}
yy4:
//line "go/fill/01_fill.re":64
{ continue }
//line "go/fill/01_fill.go":96
yy5:
in.cur += 1
in.mar = in.cur
yyFillLabel2:
yych = in.buf[in.cur]
if (yych >= 0x01) {
goto yy7
}
if (in.lim <= in.cur) {
if (fill(in) == 0) {
goto yyFillLabel2
}
goto yy2
}
yy6:
in.cur += 1
yyFillLabel3:
yych = in.buf[in.cur]
yy7:
switch (yych) {
case '\'':
goto yy8
case '\\':
goto yy9
default:
if (in.lim <= in.cur) {
if (fill(in) == 0) {
goto yyFillLabel3
}
goto yy11
}
goto yy6
}
yy8:
in.cur += 1
//line "go/fill/01_fill.re":63
{ count += 1; continue }
//line "go/fill/01_fill.go":134
yy9:
in.cur += 1
yyFillLabel4:
yych = in.buf[in.cur]
if (yych <= 0x00) {
if (in.lim <= in.cur) {
if (fill(in) == 0) {
goto yyFillLabel4
}
goto yy11
}
goto yy6
}
goto yy6
yy10:
//line "go/fill/01_fill.re":62
{ return count }
//line "go/fill/01_fill.go":152
yy11:
in.cur = in.mar
goto yy2
}
//line "go/fill/01_fill.re":65
}
}
func main() () {
fname := "input"
content := "'qu\000tes' 'are' 'fine: \\'' ";
// Prepare input file: a few times the size of the buffer, containing
// strings with zeroes and escaped quotes.
f, _ := os.Create(fname)
f.WriteString(strings.Repeat(content, BUFSIZE))
f.Seek(0, 0)
count := 3 * BUFSIZE // number of quoted strings written to file
// Prepare lexer state: all offsets are at the end of buffer.
in := &Input{
file: f,
// Sentinel at `lim` offset is set to zero, which triggers YYFILL.
buf: make([]byte, BUFSIZE+1),
cur: BUFSIZE,
mar: BUFSIZE,
tok: BUFSIZE,
lim: BUFSIZE,
eof: false,
}
// Run the lexer.
if lex(in) != count { panic("error"); }
// Cleanup: remove input file.
f.Close();
os.Remove(fname);
}