diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/spec.go | 153 |
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"` |