2017-07-07 11:41:37 +02:00
|
|
|
package parser
|
2017-06-29 18:20:16 +02:00
|
|
|
|
|
|
|
import "fmt"
|
|
|
|
|
2017-07-09 17:18:35 +02:00
|
|
|
// A Token is either an object {{a.b}}, a tag {%if a>b%}, or a text chunk (anything outside of {{}} and {%%}.)
|
|
|
|
type Token struct {
|
2017-07-10 17:49:14 +02:00
|
|
|
Type TokenType
|
|
|
|
SourceLoc SourceLoc
|
|
|
|
Name string // Name is the tag name of a tag Chunk. E.g. the tag name of "{% if 1 %}" is "if".
|
|
|
|
Args string // Parameters is the tag arguments of a tag Chunk. E.g. the tag arguments of "{% if 1 %}" is "1".
|
|
|
|
Source string // Source is the entirety of the token, including the "{{", "{%", etc. markers.
|
2017-06-29 18:20:16 +02:00
|
|
|
}
|
|
|
|
|
2017-07-09 17:18:35 +02:00
|
|
|
// TokenType is the type of a Chunk
|
|
|
|
type TokenType int
|
2017-06-30 14:42:11 +02:00
|
|
|
|
2017-07-14 02:18:23 +02:00
|
|
|
////go:generate stringer -type=TokenType
|
2017-07-04 16:25:29 +02:00
|
|
|
|
2017-06-30 14:42:11 +02:00
|
|
|
const (
|
2017-07-09 17:18:35 +02:00
|
|
|
// TextTokenType is the type of a text Chunk
|
|
|
|
TextTokenType TokenType = iota
|
|
|
|
// TagTokenType is the type of a tag Chunk "{%…%}"
|
|
|
|
TagTokenType
|
|
|
|
// ObjTokenType is the type of an object Chunk "{{…}}"
|
|
|
|
ObjTokenType
|
2017-06-30 14:42:11 +02:00
|
|
|
)
|
|
|
|
|
2017-07-10 17:49:14 +02:00
|
|
|
// SourceLoc contains a Token's source location.
|
|
|
|
type SourceLoc struct {
|
2017-06-30 14:42:11 +02:00
|
|
|
Pathname string
|
2017-07-10 17:49:14 +02:00
|
|
|
LineNo int
|
2017-06-30 14:42:11 +02:00
|
|
|
}
|
|
|
|
|
2017-07-10 17:49:14 +02:00
|
|
|
// SourceLocation returns the token's source location, for use in error reporting.
|
|
|
|
func (c Token) SourceLocation() SourceLoc { return c.SourceLoc }
|
|
|
|
|
|
|
|
// SourceText returns the token's source text, for use in error reporting.
|
|
|
|
func (c Token) SourceText() string { return c.Source }
|
|
|
|
|
2017-07-14 16:17:34 +02:00
|
|
|
// IsZero returns a boolean indicating whether the location doesn't have a set path.
|
|
|
|
func (s SourceLoc) IsZero() bool { return s.Pathname == "" }
|
|
|
|
|
|
|
|
|
2017-07-09 17:18:35 +02:00
|
|
|
func (c Token) String() string {
|
2017-06-29 18:20:16 +02:00
|
|
|
switch c.Type {
|
2017-07-09 17:18:35 +02:00
|
|
|
case TextTokenType:
|
2017-07-02 05:52:23 +02:00
|
|
|
return fmt.Sprintf("%v{%#v}", c.Type, c.Source)
|
2017-07-09 17:18:35 +02:00
|
|
|
case TagTokenType:
|
2017-07-02 05:52:23 +02:00
|
|
|
return fmt.Sprintf("%v{Tag:%#v, Args:%#v}", c.Type, c.Name, c.Args)
|
2017-07-09 17:18:35 +02:00
|
|
|
case ObjTokenType:
|
2017-07-02 05:52:23 +02:00
|
|
|
return fmt.Sprintf("%v{%#v}", c.Type, c.Args)
|
2017-06-29 18:20:16 +02:00
|
|
|
default:
|
2017-07-02 05:52:23 +02:00
|
|
|
return fmt.Sprintf("%v{%#v}", c.Type, c.Source)
|
2017-06-29 18:20:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-10 17:49:14 +02:00
|
|
|
func (s SourceLoc) String() string {
|
2017-06-30 14:42:11 +02:00
|
|
|
if s.Pathname != "" {
|
2017-07-10 17:49:14 +02:00
|
|
|
return fmt.Sprintf("%s:%d", s.Pathname, s.LineNo)
|
2017-06-30 14:42:11 +02:00
|
|
|
}
|
2017-07-10 17:49:14 +02:00
|
|
|
return fmt.Sprintf("line %d", s.LineNo)
|
2017-06-29 18:20:16 +02:00
|
|
|
}
|