summaryrefslogtreecommitdiff
path: root/lang
diff options
context:
space:
mode:
Diffstat (limited to 'lang')
-rw-r--r--lang/golang/go.go239
-rw-r--r--lang/spec.go28
-rw-r--r--lang/token.go3
3 files changed, 196 insertions, 74 deletions
diff --git a/lang/golang/go.go b/lang/golang/go.go
index 47baee2..b1213e5 100644
--- a/lang/golang/go.go
+++ b/lang/golang/go.go
@@ -53,75 +53,180 @@ var GoSpec = &lang.Spec{
"/*": lang.CharStr,
"//": lang.CharStr | lang.ExcludeEnd | lang.EosValidEnd,
},
- TokenProps: map[string]lang.TokenProp{
- // Block tokens (can be nested)
- "{..}": {Token: lang.BraceBlock},
- "[..]": {Token: lang.BracketBlock},
- "(..)": {Token: lang.ParenBlock},
+ Tokens: map[string]lang.Token{
+ "{..}": lang.BraceBlock,
+ "[..]": lang.BracketBlock,
+ "(..)": lang.ParenBlock,
+ "//..": lang.Comment,
+ "/*..": lang.Comment,
+ `".."`: lang.String,
+ "`..`": lang.String,
+ ",": lang.Comma,
+ ";": lang.Semicolon,
+ ".": lang.Period,
+ ":": lang.Colon,
+ "&": lang.And,
+ "*": lang.Mul,
+ "/": lang.Quo,
+ "%": lang.Rem,
+ "<<": lang.Shl,
+ ">>": lang.Shr,
+ "+": lang.Add,
+ "-": lang.Sub,
+ "=": lang.Assign,
+ "+=": lang.AddAssign,
+ "<": lang.Less,
+ ">": lang.Greater,
+ "^": lang.Xor,
+ "~": lang.Tilde,
+ "&&": lang.Land,
+ "||": lang.Lor,
+ ":=": lang.Define,
+ "==": lang.Equal,
+ "<=": lang.LessEqual,
+ ">=": lang.GreaterEqual,
+ "->": lang.Arrow,
+ "!": lang.Not,
+ "++": lang.Inc,
+ "--": lang.Dec,
+ "break": lang.Break,
+ "case": lang.Case,
+ "chan": lang.Chan,
+ "const": lang.Const,
+ "continue": lang.Continue,
+ "default": lang.Default,
+ "defer": lang.Defer,
+ "else": lang.Else,
+ "fallthrough": lang.Fallthrough,
+ "for": lang.For,
+ "func": lang.Func,
+ "go": lang.Go,
+ "goto": lang.Goto,
+ "if": lang.If,
+ "import": lang.Import,
+ "interface": lang.Interface,
+ "map": lang.Map,
+ "package": lang.Package,
+ "range": lang.Range,
+ "return": lang.Return,
+ "select": lang.Select,
+ "struct": lang.Struct,
+ "switch": lang.Switch,
+ "type": lang.Type,
+ "var": lang.Var,
+ },
+ TokenProps: []lang.TokenProp{
+ lang.And: {Precedence: 5},
+ lang.Mul: {Precedence: 5},
+ lang.Quo: {Precedence: 5},
+ lang.Rem: {Precedence: 5},
+ lang.Shl: {Precedence: 5},
+ lang.Shr: {Precedence: 5},
+ lang.Add: {Precedence: 4},
+ lang.Sub: {Precedence: 4},
+ lang.Xor: {Precedence: 4},
+ lang.Or: {Precedence: 4},
+ lang.LessEqual: {Precedence: 3},
+ lang.GreaterEqual: {Precedence: 3},
+ lang.Less: {Precedence: 3},
+ lang.Greater: {Precedence: 3},
+ lang.Land: {Precedence: 2},
+ lang.Lor: {Precedence: 1},
+ lang.Inc: {SkipSemi: true},
+ lang.Dec: {SkipSemi: true},
+ lang.Case: {SkipSemi: true},
+ lang.Chan: {SkipSemi: true},
+ lang.Const: {SkipSemi: true},
+ lang.Default: {SkipSemi: true},
+ lang.Defer: {SkipSemi: true},
+ lang.Else: {SkipSemi: true},
+ lang.For: {SkipSemi: true},
+ lang.Func: {SkipSemi: true},
+ lang.Go: {SkipSemi: true},
+ lang.Goto: {SkipSemi: true},
+ lang.If: {SkipSemi: true},
+ lang.Import: {SkipSemi: true},
+ lang.Interface: {SkipSemi: true},
+ lang.Map: {SkipSemi: true},
+ lang.Package: {SkipSemi: true},
+ lang.Range: {SkipSemi: true},
+ lang.Select: {SkipSemi: true},
+ lang.Struct: {SkipSemi: true},
+ lang.Switch: {SkipSemi: true},
+ lang.Type: {SkipSemi: true},
+ lang.Var: {SkipSemi: true},
+ },
+ /*
+ TokenProps: map[string]lang.TokenProp{
+ // Block tokens (can be nested)
+ "{..}": {Token: lang.BraceBlock},
+ "[..]": {Token: lang.BracketBlock},
+ "(..)": {Token: lang.ParenBlock},
- // String tokens (not nested)
- "//..": {Token: lang.Comment},
- "/*..": {Token: lang.Comment},
- `".."`: {Token: lang.String},
- "`..`": {Token: lang.String},
+ // String tokens (not nested)
+ "//..": {Token: lang.Comment},
+ "/*..": {Token: lang.Comment},
+ `".."`: {Token: lang.String},
+ "`..`": {Token: lang.String},
- // Separators
- ",": {Token: lang.Comma},
- ";": {Token: lang.Semicolon},
- ".": {Token: lang.Period},
- ":": {Token: lang.Colon},
+ // Separators
+ ",": {Token: lang.Comma},
+ ";": {Token: lang.Semicolon},
+ ".": {Token: lang.Period},
+ ":": {Token: lang.Colon},
- // Operators
- "&": {Token: lang.And, Precedence: 1},
- "*": {Token: lang.Mul, Precedence: 1},
- "/": {Token: lang.Quo, Precedence: 1},
- "%": {Token: lang.Rem, Precedence: 1},
- "<<": {Token: lang.Shl, Precedence: 1},
- ">>": {Token: lang.Shr, Precedence: 1},
- "+": {Token: lang.Add, Precedence: 2},
- "-": {Token: lang.Sub, Precedence: 2},
- "=": {Token: lang.Assign, Precedence: 6},
- "+=": {Token: lang.AddAssign, Precedence: 6},
- "<": {Token: lang.Less, Precedence: 3},
- ">": {Token: lang.Greater, Precedence: 3},
- "^": {Token: lang.Xor, Precedence: 2},
- "~": {Token: lang.Tilde},
- "&&": {Token: lang.Land, Precedence: 4},
- "||": {Token: lang.Lor, Precedence: 5},
- ":=": {Token: lang.Define, Precedence: 6},
- "==": {Token: lang.Equal, Precedence: 3},
- "<=": {Token: lang.LessEqual, Precedence: 3},
- ">=": {Token: lang.GreaterEqual, Precedence: 3},
- "->": {Token: lang.Arrow},
- "!": {Token: lang.Not},
- "++": {Token: lang.Inc, SkipSemi: true},
- "--": {Token: lang.Dec, SkipSemi: true},
+ // Operators
+ "&": {Token: lang.And, Precedence: 1},
+ "*": {Token: lang.Mul, Precedence: 3},
+ "/": {Token: lang.Quo, Precedence: 1},
+ "%": {Token: lang.Rem, Precedence: 1},
+ "<<": {Token: lang.Shl, Precedence: 1},
+ ">>": {Token: lang.Shr, Precedence: 1},
+ "+": {Token: lang.Add, Precedence: 2},
+ "-": {Token: lang.Sub, Precedence: 2},
+ "=": {Token: lang.Assign, Precedence: 1},
+ "+=": {Token: lang.AddAssign, Precedence: 1},
+ "<": {Token: lang.Less, Precedence: 1},
+ ">": {Token: lang.Greater, Precedence: 1},
+ "^": {Token: lang.Xor, Precedence: 2},
+ "~": {Token: lang.Tilde},
+ "&&": {Token: lang.Land, Precedence: 4},
+ "||": {Token: lang.Lor, Precedence: 5},
+ ":=": {Token: lang.Define, Precedence: 1},
+ "==": {Token: lang.Equal, Precedence: 1},
+ "<=": {Token: lang.LessEqual, Precedence: 1},
+ ">=": {Token: lang.GreaterEqual, Precedence: 1},
+ "->": {Token: lang.Arrow},
+ "!": {Token: lang.Not},
+ "++": {Token: lang.Inc, SkipSemi: true},
+ "--": {Token: lang.Dec, SkipSemi: true},
- // Reserved keywords
- "break": {Token: lang.Break},
- "case": {Token: lang.Case, SkipSemi: true},
- "chan": {Token: lang.Chan, SkipSemi: true},
- "const": {Token: lang.Const, SkipSemi: true},
- "continue": {Token: lang.Continue},
- "default": {Token: lang.Case, SkipSemi: true},
- "defer": {Token: lang.Defer, SkipSemi: true},
- "else": {Token: lang.Else, SkipSemi: true},
- "fallthrough": {Token: lang.Fallthrough},
- "for": {Token: lang.For, SkipSemi: true},
- "func": {Token: lang.Func, SkipSemi: true},
- "go": {Token: lang.Go, SkipSemi: true},
- "goto": {Token: lang.Goto, SkipSemi: true},
- "if": {Token: lang.If, SkipSemi: true},
- "import": {Token: lang.Import, SkipSemi: true},
- "interface": {Token: lang.Interface, SkipSemi: true},
- "map": {Token: lang.Map, SkipSemi: true},
- "package": {Token: lang.Package, SkipSemi: true},
- "range": {Token: lang.Range, SkipSemi: true},
- "return": {Token: lang.Return},
- "select": {Token: lang.Select, SkipSemi: true},
- "struct": {Token: lang.Struct, SkipSemi: true},
- "switch": {Token: lang.Switch, SkipSemi: true},
- "type": {Token: lang.Type, SkipSemi: true},
- "var": {Token: lang.Var, SkipSemi: true},
- },
+ // Reserved keywords
+ "break": {Token: lang.Break},
+ "case": {Token: lang.Case, SkipSemi: true},
+ "chan": {Token: lang.Chan, SkipSemi: true},
+ "const": {Token: lang.Const, SkipSemi: true},
+ "continue": {Token: lang.Continue},
+ "default": {Token: lang.Case, SkipSemi: true},
+ "defer": {Token: lang.Defer, SkipSemi: true},
+ "else": {Token: lang.Else, SkipSemi: true},
+ "fallthrough": {Token: lang.Fallthrough},
+ "for": {Token: lang.For, SkipSemi: true},
+ "func": {Token: lang.Func, SkipSemi: true},
+ "go": {Token: lang.Go, SkipSemi: true},
+ "goto": {Token: lang.Goto, SkipSemi: true},
+ "if": {Token: lang.If, SkipSemi: true},
+ "import": {Token: lang.Import, SkipSemi: true},
+ "interface": {Token: lang.Interface, SkipSemi: true},
+ "map": {Token: lang.Map, SkipSemi: true},
+ "package": {Token: lang.Package, SkipSemi: true},
+ "range": {Token: lang.Range, SkipSemi: true},
+ "return": {Token: lang.Return},
+ "select": {Token: lang.Select, SkipSemi: true},
+ "struct": {Token: lang.Struct, SkipSemi: true},
+ "switch": {Token: lang.Switch, SkipSemi: true},
+ "type": {Token: lang.Type, SkipSemi: true},
+ "var": {Token: lang.Var, SkipSemi: true},
+ },
+ */
}
diff --git a/lang/spec.go b/lang/spec.go
index b1b2580..37017e7 100644
--- a/lang/spec.go
+++ b/lang/spec.go
@@ -21,22 +21,36 @@ const (
// ASCIILen is the length of the ASCII characters set.
const ASCIILen = 1 << 7 // 128
+// Associativity represent the associativity rule of an operator.
+type Associativity int
+
+// Associativity kinds for operators.
+const (
+ Aboth Associativity = iota // both left and right associative
+ Aleft // left associative only
+ Aright // right associative only
+ Anon // non associative
+)
+
// TokenProp represent token properties for parsing.
type TokenProp struct {
Token
SkipSemi bool // automatic semicolon insertion after newline
Precedence int // operator precedence
+ Associativity
}
// Spec represents the language specification for scanning.
type Spec struct {
- CharProp [ASCIILen]uint // special Character properties
- End map[string]string // end delimiters, indexed by start
- BlockProp map[string]uint // block properties
- TokenProps map[string]TokenProp // token properties
- DotNum bool // true if a number can start with '.'
- IdentASCII bool // true if an identifier can be in ASCII only
- NumUnder bool // true if a number can contain _ character
+ CharProp [ASCIILen]uint // special Character properties
+ End map[string]string // end delimiters, indexed by start
+ BlockProp map[string]uint // block properties
+ Tokens map[string]Token // token per string
+ TokenProps []TokenProp // token properties, indexed by token
+ DotNum bool // true if a number can start with '.'
+ IdentASCII bool // true if an identifier can be in ASCII only
+ NumUnder bool // true if a number can contain _ character
+ // TokenProps map[string]TokenProp // token properties
}
// HasInit stores if a statement may contain a simple init statement.
diff --git a/lang/token.go b/lang/token.go
index 41c8439..4f5da35 100644
--- a/lang/token.go
+++ b/lang/token.go
@@ -120,6 +120,9 @@ const (
JumpSetTrue
Label
New
+
+ // This must be the last token value.
+ MaxTok
)
// UnaryOp contains the set of unary operators.