diff options
Diffstat (limited to 'spec/lexer.go')
-rw-r--r-- | spec/lexer.go | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/spec/lexer.go b/spec/lexer.go index c1c4b0d..d1f3ae7 100644 --- a/spec/lexer.go +++ b/spec/lexer.go @@ -7,6 +7,7 @@ import ( _ "embed" "fmt" "io" + "regexp" "strings" verr "github.com/nihei9/vartan/error" @@ -33,6 +34,11 @@ const ( tokenKindInvalid = tokenKind("invalid") ) +var ( + reIDChar = regexp.MustCompile(`^[0-9a-z_]+$`) + reIDInvalidDigitsPos = regexp.MustCompile(`^[0-9]`) +) + type Position struct { Row int Col int @@ -167,9 +173,33 @@ func (l *lexer) lexAndSkipWSs() (*token, error) { case KindIDKwFragment: return newSymbolToken(tokenKindKWFragment, newPosition(tok.Row+1, tok.Col+1)), nil case KindIDIdentifier: - if strings.HasPrefix(string(tok.Lexeme), "_") { + if !reIDChar.Match(tok.Lexeme) { + return nil, &verr.SpecError{ + Cause: synErrIDInvalidChar, + Detail: string(tok.Lexeme), + Row: tok.Row + 1, + Col: tok.Col + 1, + } + } + if strings.HasPrefix(string(tok.Lexeme), "_") || strings.HasSuffix(string(tok.Lexeme), "_") { + return nil, &verr.SpecError{ + Cause: synErrIDInvalidUnderscorePos, + Detail: string(tok.Lexeme), + Row: tok.Row + 1, + Col: tok.Col + 1, + } + } + if strings.Contains(string(tok.Lexeme), "__") { + return nil, &verr.SpecError{ + Cause: synErrIDConsecutiveUnderscores, + Detail: string(tok.Lexeme), + Row: tok.Row + 1, + Col: tok.Col + 1, + } + } + if reIDInvalidDigitsPos.Match(tok.Lexeme) { return nil, &verr.SpecError{ - Cause: synErrAutoGenID, + Cause: synErrIDInvalidDigitsPos, Detail: string(tok.Lexeme), Row: tok.Row + 1, Col: tok.Col + 1, |