in cmd/goyacc/yacc.go [828:998]
func gettok() int {
var i int
var match, c rune
tokname = ""
for {
lineno += peekline
peekline = 0
c = getrune(finput)
for c == ' ' || c == '\n' || c == '\t' || c == '\v' || c == '\r' {
if c == '\n' {
lineno++
}
c = getrune(finput)
}
// skip comment -- fix
if c != '/' {
break
}
lineno += skipcom()
}
switch c {
case EOF:
if tokflag {
fmt.Printf(">>> ENDFILE %v\n", lineno)
}
return ENDFILE
case '{':
ungetrune(finput, c)
if tokflag {
fmt.Printf(">>> ={ %v\n", lineno)
}
return '='
case '<':
// get, and look up, a type name (union member name)
c = getrune(finput)
for c != '>' && c != EOF && c != '\n' {
tokname += string(c)
c = getrune(finput)
}
if c != '>' {
errorf("unterminated < ... > clause")
}
for i = 1; i <= ntypes; i++ {
if typeset[i] == tokname {
numbval = i
if tokflag {
fmt.Printf(">>> TYPENAME old <%v> %v\n", tokname, lineno)
}
return TYPENAME
}
}
ntypes++
numbval = ntypes
typeset[numbval] = tokname
if tokflag {
fmt.Printf(">>> TYPENAME new <%v> %v\n", tokname, lineno)
}
return TYPENAME
case '"', '\'':
match = c
tokname = string(c)
for {
c = getrune(finput)
if c == '\n' || c == EOF {
errorf("illegal or missing ' or \"")
}
if c == '\\' {
tokname += string('\\')
c = getrune(finput)
} else if c == match {
if tokflag {
fmt.Printf(">>> IDENTIFIER \"%v\" %v\n", tokname, lineno)
}
tokname += string(c)
return IDENTIFIER
}
tokname += string(c)
}
case '%':
c = getrune(finput)
switch c {
case '%':
if tokflag {
fmt.Printf(">>> MARK %%%% %v\n", lineno)
}
return MARK
case '=':
if tokflag {
fmt.Printf(">>> PREC %%= %v\n", lineno)
}
return PREC
case '{':
if tokflag {
fmt.Printf(">>> LCURLY %%{ %v\n", lineno)
}
return LCURLY
}
getword(c)
// find a reserved word
for i := range resrv {
if tokname == resrv[i].name {
if tokflag {
fmt.Printf(">>> %%%v %v %v\n", tokname,
resrv[i].value-PRIVATE, lineno)
}
return resrv[i].value
}
}
errorf("invalid escape, or illegal reserved word: %v", tokname)
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
numbval = int(c - '0')
for {
c = getrune(finput)
if !isdigit(c) {
break
}
numbval = numbval*10 + int(c-'0')
}
ungetrune(finput, c)
if tokflag {
fmt.Printf(">>> NUMBER %v %v\n", numbval, lineno)
}
return NUMBER
default:
if isword(c) || c == '.' || c == '$' {
getword(c)
break
}
if tokflag {
fmt.Printf(">>> OPERATOR %v %v\n", string(c), lineno)
}
return int(c)
}
// look ahead to distinguish IDENTIFIER from IDENTCOLON
c = getrune(finput)
for c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\r' || c == '/' {
if c == '\n' {
peekline++
}
// look for comments
if c == '/' {
peekline += skipcom()
}
c = getrune(finput)
}
if c == ':' {
if tokflag {
fmt.Printf(">>> IDENTCOLON %v: %v\n", tokname, lineno)
}
return IDENTCOLON
}
ungetrune(finput, c)
if tokflag {
fmt.Printf(">>> IDENTIFIER %v %v\n", tokname, lineno)
}
return IDENTIFIER
}