aboutsummaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/spec.go153
1 files changed, 92 insertions, 61 deletions
diff --git a/spec/spec.go b/spec/spec.go
index b8aae33..d4f6346 100644
--- a/spec/spec.go
+++ b/spec/spec.go
@@ -7,40 +7,56 @@ import (
"strings"
)
-const lexKindPattern = "[A-Za-z_][0-9A-Za-z_]*"
+// LexKindID represents an ID of a lexical kind and is unique across all modes.
+type LexKindID int
+
+const (
+ LexKindIDNil = LexKindID(0)
+ LexKindIDMin = LexKindID(1)
+)
+
+func (id LexKindID) Int() int {
+ return int(id)
+}
+
+// LexModeKindID represents an ID of a lexical kind and is unique within a mode.
+// Use LexKindID to identify a kind across all modes uniquely.
+type LexModeKindID int
+
+const (
+ LexModeKindIDNil = LexKindID(0)
+ LexModeKindIDMin = LexKindID(1)
+)
-var lexKindRE = regexp.MustCompile(lexKindPattern)
+func (id LexModeKindID) Int() int {
+ return int(id)
+}
-type LexKind string
+// LexKindName represents a name of a lexical kind.
+type LexKindName string
-const LexKindNil = LexKind("")
+const LexKindNameNil = LexKindName("")
-func (k LexKind) String() string {
+func (k LexKindName) String() string {
return string(k)
}
-func (k LexKind) validate() error {
+func (k LexKindName) validate() error {
if k == "" {
return fmt.Errorf("kind doesn't allow to be the empty string")
}
- if !lexKindRE.Match([]byte(k)) {
- return fmt.Errorf("kind must be %v", lexKindPattern)
+ if !lexKindNameRE.Match([]byte(k)) {
+ return fmt.Errorf("kind must be %v", lexKindNamePattern)
}
return nil
}
-// LexKindID is a unique ID among modes.
-type LexKindID int
-
-func (id LexKindID) Int() int {
- return int(id)
-}
+const lexKindNamePattern = "[A-Za-z_][0-9A-Za-z_]*"
-const (
- LexKindIDNil = LexKindID(0)
- LexKindIDMin = LexKindID(1)
-)
+var lexKindNameRE = regexp.MustCompile(lexKindNamePattern)
+// LexPattern represents a pattern of a lexeme.
+// The pattern is written in regular expression.
type LexPattern string
func (p LexPattern) validate() error {
@@ -50,10 +66,27 @@ func (p LexPattern) validate() error {
return nil
}
-const lexModePattern = "[A-Za-z_][0-9A-Za-z_]*"
+// LexModeID represents an ID of a lex mode.
+type LexModeID int
-var lexModeRE = regexp.MustCompile(lexKindPattern)
+const (
+ LexModeIDNil = LexModeID(0)
+ LexModeIDDefault = LexModeID(1)
+)
+func (n LexModeID) String() string {
+ return strconv.Itoa(int(n))
+}
+
+func (n LexModeID) Int() int {
+ return int(n)
+}
+
+func (n LexModeID) IsNil() bool {
+ return n == LexModeIDNil
+}
+
+// LexModeName represents a name of a lex mode.
type LexModeName string
const (
@@ -66,8 +99,8 @@ func (m LexModeName) String() string {
}
func (m LexModeName) validate() error {
- if m.isNil() || !lexModeRE.Match([]byte(m)) {
- return fmt.Errorf("mode must be %v", lexModePattern)
+ if m.isNil() || !lexModeNameRE.Match([]byte(m)) {
+ return fmt.Errorf("mode must be %v", lexModeNamePattern)
}
return nil
}
@@ -76,31 +109,12 @@ func (m LexModeName) isNil() bool {
return m == LexModeNameNil
}
-type LexModeNum int
+const lexModeNamePattern = "[A-Za-z_][0-9A-Za-z_]*"
-const (
- LexModeNumNil = LexModeNum(0)
- LexModeNumDefault = LexModeNum(1)
-)
-
-func (n LexModeNum) String() string {
- return strconv.Itoa(int(n))
-}
-
-func (n LexModeNum) Int() int {
- return int(n)
-}
-
-func (n LexModeNum) Succ() LexModeNum {
- return n + 1
-}
-
-func (n LexModeNum) IsNil() bool {
- return n == LexModeNumNil
-}
+var lexModeNameRE = regexp.MustCompile(lexModeNamePattern)
type LexEntry struct {
- Kind LexKind `json:"kind"`
+ Kind LexKindName `json:"kind"`
Pattern LexPattern `json:"pattern"`
Modes []LexModeName `json:"modes"`
Push LexModeName `json:"push"`
@@ -174,18 +188,35 @@ func (s *LexSpec) Validate() error {
return nil
}
+// StateID represents an ID of a state of a transition table.
+type StateID int
+
+const (
+ // StateIDNil represents an empty entry of a transition table.
+ // When the driver reads this value, it raises an error meaning lexical analysis failed.
+ StateIDNil = StateID(0)
+
+ // StateIDMin is the minimum value of the state ID. All valid state IDs are represented as
+ // sequential numbers starting from this value.
+ StateIDMin = StateID(1)
+)
+
+func (id StateID) Int() int {
+ return int(id)
+}
+
type RowDisplacementTable struct {
- OriginalRowCount int `json:"original_row_count"`
- OriginalColCount int `json:"original_col_count"`
- EmptyValue int `json:"empty_value"`
- Entries []int `json:"entries"`
- Bounds []int `json:"bounds"`
- RowDisplacement []int `json:"row_displacement"`
+ OriginalRowCount int `json:"original_row_count"`
+ OriginalColCount int `json:"original_col_count"`
+ EmptyValue StateID `json:"empty_value"`
+ Entries []StateID `json:"entries"`
+ Bounds []int `json:"bounds"`
+ RowDisplacement []int `json:"row_displacement"`
}
type UniqueEntriesTable struct {
UniqueEntries *RowDisplacementTable `json:"unique_entries,omitempty"`
- UncompressedUniqueEntries []int `json:"uncompressed_unique_entries,omitempty"`
+ UncompressedUniqueEntries []StateID `json:"uncompressed_unique_entries,omitempty"`
RowNums []int `json:"row_nums"`
OriginalRowCount int `json:"original_row_count"`
OriginalColCount int `json:"original_col_count"`
@@ -193,25 +224,25 @@ type UniqueEntriesTable struct {
}
type TransitionTable struct {
- InitialState int `json:"initial_state"`
- AcceptingStates []int `json:"accepting_states"`
+ InitialStateID StateID `json:"initial_state_id"`
+ AcceptingStates []LexModeKindID `json:"accepting_states"`
RowCount int `json:"row_count"`
ColCount int `json:"col_count"`
Transition *UniqueEntriesTable `json:"transition,omitempty"`
- UncompressedTransition []int `json:"uncompressed_transition,omitempty"`
+ UncompressedTransition []StateID `json:"uncompressed_transition,omitempty"`
}
type CompiledLexModeSpec struct {
- Kinds []LexKind `json:"kinds"`
- Push []LexModeNum `json:"push"`
- Pop []int `json:"pop"`
- DFA *TransitionTable `json:"dfa"`
+ KindNames []LexKindName `json:"kind_names"`
+ Push []LexModeID `json:"push"`
+ Pop []int `json:"pop"`
+ DFA *TransitionTable `json:"dfa"`
}
type CompiledLexSpec struct {
- InitialMode LexModeNum `json:"initial_mode"`
- Modes []LexModeName `json:"modes"`
- Kinds []LexKind `json:"kinds"`
+ InitialModeID LexModeID `json:"initial_mode_id"`
+ ModeNames []LexModeName `json:"mode_names"`
+ KindNames []LexKindName `json:"kind_names"`
KindIDs [][]LexKindID `json:"kind_ids"`
CompressionLevel int `json:"compression_level"`
Specs []*CompiledLexModeSpec `json:"specs"`