aboutsummaryrefslogtreecommitdiff
path: root/spec/lexer.go
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lexer.go')
-rw-r--r--spec/lexer.go34
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,