Prechádzať zdrojové kódy

Commit old stuff before restarting on new branch.

Beoran 2 rokov pred
rodič
commit
ed36a5761c
6 zmenil súbory, kde vykonal 638 pridanie a 153 odobranie
  1. 20 1
      ll1.go
  2. 32 5
      ll1.parser.go.lined.tpl
  3. 31 5
      ll1.parser.go.tpl
  4. 415 142
      ll1_parser.go
  5. 138 0
      parser.go
  6. 2 0
      template_functions.go

+ 20 - 1
ll1.go

@@ -17,7 +17,8 @@ Rule -> Name arrow Definition.
 Name -> identifier .
 Name -> identifier .
 Definition -> Alternates . // Alternates have a higher priority than sequences.
 Definition -> Alternates . // Alternates have a higher priority than sequences.
 Alternates -> Sequence or Alternates | .
 Alternates -> Sequence or Alternates | .
-Sequence -> Element Sequence | . 
+Sequence -> Element Sequence | Operator Sequence | . 
+Operator -> plus Element | star Element .
 Element -> Parenthesis | Terminal | Literal .
 Element -> Parenthesis | Terminal | Literal .
 Parenthesis -> '(' Definition ')' .
 Parenthesis -> '(' Definition ')' .
 Terminal -> identifier .
 Terminal -> identifier .
@@ -305,6 +306,24 @@ func (s Set) String() string {
     return strings.Join(aid, " ")
     return strings.Join(aid, " ")
 }
 }
 
 
+func (s Set) ToTokenKinds() []rune {
+    if len(s) == 0 {
+        return []rune{}
+    }    
+    aid := []rune{}
+    for _, v := range s {
+        t , ok := v.(Terminal)
+        if !ok { 
+            continue 
+        }
+        if len(t.token.Value) == 1 {
+            aid = append(aid, rune(t.token.Value[0]))
+        }
+    }
+    return aid
+}
+
+
 // Definition of a rule is nothing but a set of alternates,
 // Definition of a rule is nothing but a set of alternates,
 // where alternates can contain sequences and parenthesis.
 // where alternates can contain sequences and parenthesis.
 type Definition = Alternates
 type Definition = Alternates

+ 32 - 5
ll1.parser.go.lined.tpl

@@ -348,14 +348,41 @@ func ( *{{$Lexer}}) Lex{{$TokenKindName}}() ({{$TokenKind}}, error) {
 {{ $RuleType := ( printf "%s%s" $prefix $ruleName) }}
 {{ $RuleType := ( printf "%s%s" $prefix $ruleName) }}
 
 
 //line ll1.parser.go.tpl:324
 //line ll1.parser.go.tpl:324
-type {{$RuleType}} struct {    
+type {{$RuleType}} struct {
+    {{$Token}}
+    {{ range .Definition.Sequences -}}
+        {{- range .Elements -}}
+            {{- if (IsNonterminal .) -}}
+                *{{$prefix}}{{ . }}
+            {{ end -}}
+        {{- end}}
+    {{ end -}}
 }
 }
 
 
+//line ll1.parser.go.tpl:335
+func (p *{{$Parser}}) Is{{$RuleType}}() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *{{$Parser}}) Parse{{$RuleType}}() ({{$RuleType}}, error) {
-    result := {{$RuleType}} {}
-    return result, nil 
+//line ll1.parser.go.tpl:340
+func (p *{{$Parser}}) Parse{{$RuleType}}() (*{{$RuleType}}, error) {
+    var err error
+    result := &{{$RuleType}} { {{$Token}}: p.current }
+    {{ range .Definition.Sequences -}}
+        {{- range .Elements -}}
+            {{- if (IsNonterminal .) -}}
+            {{- $fn := (printf "%s%s" $prefix .)}}
+    if p.Is{{$fn}}() {
+        result.{{$fn}}, err = p.Parse{{$fn}}()
+        if err != nil {
+            return result, err
+        }
+    }
+            {{ end -}}
+        {{- end}}
+    {{ end -}}    
+    return result, err
 }
 }
 {{end}}
 {{end}}
 
 

+ 31 - 5
ll1.parser.go.tpl

@@ -307,7 +307,7 @@ func (parser {{$Parser}}) NextIs(kinds ...{{$TokenKind}}) bool {
 {{ .Template }}
 {{ .Template }}
 {{ end }}
 {{ end }}
 {{- $terminal := .IsTerminal -}}
 {{- $terminal := .IsTerminal -}}
-{{- if $terminal -}}
+{{- if $  -}}
 {{- $TokenKindName := ( printf "%s%s" $TokenKind $ruleName) -}}
 {{- $TokenKindName := ( printf "%s%s" $TokenKind $ruleName) -}}
 
 
 const {{$TokenKindName}} {{$TokenKind}} = {{$TokenKind}}(-{{$tokenKindValue}})
 const {{$TokenKindName}} {{$TokenKind}} = {{$TokenKind}}(-{{$tokenKindValue}})
@@ -321,13 +321,39 @@ func ( *{{$Lexer}}) Lex{{$TokenKindName}}() ({{$TokenKind}}, error) {
 {{ else }}
 {{ else }}
 {{ $RuleType := ( printf "%s%s" $prefix $ruleName) }}
 {{ $RuleType := ( printf "%s%s" $prefix $ruleName) }}
 
 
-type {{$RuleType}} struct {    
+type {{$RuleType}} struct {
+    {{$Token}}
+    {{ range .Definition.Sequences -}}
+        {{- range .Elements -}}
+            {{- if (IsNonterminal .) -}}
+                *{{$prefix}}{{ . }}
+            {{ end -}}
+        {{- end}}
+    {{ end -}}
 }
 }
 
 
+func (p *{{$Parser}}) Is{{$RuleType}}() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-func ( *{{$Parser}}) Parse{{$RuleType}}() ({{$RuleType}}, error) {
-    result := {{$RuleType}} {}
-    return result, nil 
+func (p *{{$Parser}}) Parse{{$RuleType}}() (*{{$RuleType}}, error) {
+    var err error
+    result := &{{$RuleType}} { {{$Token}}: p.current }
+    {{ range .Definition.Sequences -}}
+        {{- range .Elements -}}
+            {{- if (IsNonterminal .) -}}
+            {{- $fn := (printf "%s%s" $prefix .)}}
+    if p.Is{{$fn}}() {
+        result.{{$fn}}, err = p.Parse{{$fn}}()
+        if err != nil {
+            return result, err
+        }
+    }
+            {{ end -}}
+        {{- end}}
+    {{ end -}}    
+    return result, err
 }
 }
 {{end}}
 {{end}}
 
 

+ 415 - 142
ll1_parser.go

@@ -1,6 +1,6 @@
 /* 
 /* 
  * ll1_parser.go: Parser for the Grammar grammar. 
  * ll1_parser.go: Parser for the Grammar grammar. 
- * Generated by the ll1 tool from ll1.ll1 at 2020-08-28 18:00:14.138349709 +0200 CEST m=+0.001367333.
+ * Generated by the ll1 tool from ll1.ll1 at 2020-09-07 15:48:11.467763157 +0200 CEST m=+0.001425957.
  * Based on template: ll1.parser.go.lined.tpl
  * Based on template: ll1.parser.go.lined.tpl
  * Uses a scanner
  * Uses a scanner
  * 
  * 
@@ -25,7 +25,7 @@ import "fmt"
 
 
 // This is based on strings as a default.
 // This is based on strings as a default.
 
 
-//line ll1.parser.go.tpl:43
+//no-line ll1.parser.go.tpl:43
 type Ll1Value = string
 type Ll1Value = string
 
 
 
 
@@ -34,7 +34,7 @@ type Ll1Value = string
 // Ll1Position is a position within a source file. Since the lexer is based on 
 // Ll1Position is a position within a source file. Since the lexer is based on 
 // text/scanner, we use that package's Position.
 // text/scanner, we use that package's Position.
 
 
-//line ll1.parser.go.tpl:51
+//no-line ll1.parser.go.tpl:51
 type Ll1Position = scanner.Position
 type Ll1Position = scanner.Position
 
 
 
 
@@ -44,28 +44,28 @@ type Ll1Position = scanner.Position
 // supported. EOF will be 65535 (I.e, -1 cast to rune). Non-character token 
 // supported. EOF will be 65535 (I.e, -1 cast to rune). Non-character token 
 // kinds will start from 65533 down (i.e -3, -4, -5, etc).
 // kinds will start from 65533 down (i.e -3, -4, -5, etc).
 
 
-//line ll1.parser.go.tpl:69
+//no-line ll1.parser.go.tpl:69
 type Ll1TokenKind rune
 type Ll1TokenKind rune
 
 
 
 
 // NoLl1TokenKind means "no token kind" i.e. no token. 
 // NoLl1TokenKind means "no token kind" i.e. no token. 
 
 
-//line ll1.parser.go.tpl:74
+//no-line ll1.parser.go.tpl:74
 const NoLl1TokenKind Ll1TokenKind = Ll1TokenKind(0)
 const NoLl1TokenKind Ll1TokenKind = Ll1TokenKind(0)
 // Ll1TokenKindEOF means the end of the input. 
 // Ll1TokenKindEOF means the end of the input. 
 
 
-//line ll1.parser.go.tpl:77
+//no-line ll1.parser.go.tpl:77
 const Ll1TokenKindEOF Ll1TokenKind = Ll1TokenKind(-1)
 const Ll1TokenKindEOF Ll1TokenKind = Ll1TokenKind(-1)
 // Ll1TokenKindError means a parsing or lexing error was encountered. 
 // Ll1TokenKindError means a parsing or lexing error was encountered. 
 
 
-//line ll1.parser.go.tpl:80
+//no-line ll1.parser.go.tpl:80
 const Ll1TokenKindError Ll1TokenKind = Ll1TokenKind(-2)
 const Ll1TokenKindError Ll1TokenKind = Ll1TokenKind(-2)
 
 
 
 
 
 
 // Convert token kind to a string representation
 // Convert token kind to a string representation
 
 
-//line ll1.parser.go.tpl:86
+//no-line ll1.parser.go.tpl:86
 func (tk Ll1TokenKind) String() string {
 func (tk Ll1TokenKind) String() string {
     
     
         return scanner.TokenString(rune(tk))
         return scanner.TokenString(rune(tk))
@@ -75,7 +75,7 @@ func (tk Ll1TokenKind) String() string {
 
 
 // Ll1Token is the result of a single lexical analysis step by the lexer.
 // Ll1Token is the result of a single lexical analysis step by the lexer.
 
 
-//line ll1.parser.go.tpl:109
+//no-line ll1.parser.go.tpl:109
 type Ll1Token struct {
 type Ll1Token struct {
 	Ll1Position   // Position in the source where the token was found.
 	Ll1Position   // Position in the source where the token was found.
 	Ll1TokenKind  // Type of the token
 	Ll1TokenKind  // Type of the token
@@ -85,14 +85,14 @@ type Ll1Token struct {
 
 
 // MakeLl1Token makes a token with the given position, type and value.
 // MakeLl1Token makes a token with the given position, type and value.
 
 
-//line ll1.parser.go.tpl:118
+//no-line ll1.parser.go.tpl:118
 func MakeLl1Token(pos Ll1Position, typ Ll1TokenKind, val Ll1Value) Ll1Token {
 func MakeLl1Token(pos Ll1Position, typ Ll1TokenKind, val Ll1Value) Ll1Token {
     return Ll1Token{ pos, typ, val}
     return Ll1Token{ pos, typ, val}
 }
 }
 
 
 // Ll1Lexer performs the lexical analysis of the input.
 // Ll1Lexer performs the lexical analysis of the input.
 
 
-//line ll1.parser.go.tpl:124
+//no-line ll1.parser.go.tpl:124
 type Ll1Lexer struct {
 type Ll1Lexer struct {
     // Embed scanner.Scanner
     // Embed scanner.Scanner
     scanner.Scanner
     scanner.Scanner
@@ -102,7 +102,7 @@ type Ll1Lexer struct {
 
 
 // NewLl1LexerFromReader creates a new lexer for the given parser and input.
 // NewLl1LexerFromReader creates a new lexer for the given parser and input.
 
 
-//line ll1.parser.go.tpl:133
+//no-line ll1.parser.go.tpl:133
 func NewLl1LexerFromReader(parser *Ll1Parser, reader io.Reader, filename string) *Ll1Lexer {
 func NewLl1LexerFromReader(parser *Ll1Parser, reader io.Reader, filename string) *Ll1Lexer {
     lexer := &Ll1Lexer{}
     lexer := &Ll1Lexer{}
     lexer.Filename = filename
     lexer.Filename = filename
@@ -125,7 +125,7 @@ func NewLl1LexerFromReader(parser *Ll1Parser, reader io.Reader, filename string)
 }
 }
 
 
 
 
-//line ll1.parser.go.tpl:155
+//no-line ll1.parser.go.tpl:155
 func (lex *Ll1Lexer) Lex() Ll1Token {
 func (lex *Ll1Lexer) Lex() Ll1Token {
     scanned := lex.Scanner.Scan()
     scanned := lex.Scanner.Scan()
     pos := lex.Scanner.Position
     pos := lex.Scanner.Position
@@ -151,7 +151,7 @@ func (lex *Ll1Lexer) Lex() Ll1Token {
 // Ll1Parser parses the input and returns a parse tree, 
 // Ll1Parser parses the input and returns a parse tree, 
 // based on the rules in ll1.ll1
 // based on the rules in ll1.ll1
 
 
-//line ll1.parser.go.tpl:188
+//no-line ll1.parser.go.tpl:188
 type Ll1Parser struct {
 type Ll1Parser struct {
     reader io.Reader
     reader io.Reader
     lexer *Ll1Lexer
     lexer *Ll1Lexer
@@ -162,7 +162,7 @@ type Ll1Parser struct {
 }
 }
 
 
 
 
-//line ll1.parser.go.tpl:198
+//no-line ll1.parser.go.tpl:198
 func NewLl1ParserFromReader(reader io.Reader, filename string, debug bool) *Ll1Parser {
 func NewLl1ParserFromReader(reader io.Reader, filename string, debug bool) *Ll1Parser {
     parser := &Ll1Parser{}
     parser := &Ll1Parser{}
     parser.lexer = NewLl1LexerFromReader(parser, reader, filename)
     parser.lexer = NewLl1LexerFromReader(parser, reader, filename)
@@ -179,7 +179,7 @@ func NewLl1ParserFromReader(reader io.Reader, filename string, debug bool) *Ll1P
 
 
 // Advances the parser. Returns the current token /after/ advancing.
 // Advances the parser. Returns the current token /after/ advancing.
 
 
-//line ll1.parser.go.tpl:214
+//no-line ll1.parser.go.tpl:214
 func (p *Ll1Parser) Advance() Ll1Token {
 func (p *Ll1Parser) Advance() Ll1Token {
 	token := p.lexer.Lex()
 	token := p.lexer.Lex()
     p.Debugf("Lexed token: %v", token)
     p.Debugf("Lexed token: %v", token)
@@ -191,7 +191,7 @@ func (p *Ll1Parser) Advance() Ll1Token {
 // The parser may panic with this type on errors that would prevent the parser 
 // The parser may panic with this type on errors that would prevent the parser 
 // from making progress.
 // from making progress.
 
 
-//line ll1.parser.go.tpl:225
+//no-line ll1.parser.go.tpl:225
 type Ll1ParserError struct {
 type Ll1ParserError struct {
     *Ll1Parser // Parser that had the error.
     *Ll1Parser // Parser that had the error.
     *Ll1Token  // Token at which the error was found
     *Ll1Token  // Token at which the error was found
@@ -199,14 +199,14 @@ type Ll1ParserError struct {
 }
 }
 
 
 
 
-//line ll1.parser.go.tpl:232
+//no-line ll1.parser.go.tpl:232
 func (pe Ll1ParserError) Error() string {
 func (pe Ll1ParserError) Error() string {
     // XXX will need to be improved
     // XXX will need to be improved
 	return pe.Chain.Error()
 	return pe.Chain.Error()
 }
 }
 
 
 
 
-//line ll1.parser.go.tpl:238
+//no-line ll1.parser.go.tpl:238
 func (parser *Ll1Parser) Errorf(message string, args ...interface{}) Ll1ParserError {
 func (parser *Ll1Parser) Errorf(message string, args ...interface{}) Ll1ParserError {
 	err := fmt.Errorf(message, args...)
 	err := fmt.Errorf(message, args...)
     pe := Ll1ParserError { 
     pe := Ll1ParserError { 
@@ -219,7 +219,7 @@ func (parser *Ll1Parser) Errorf(message string, args ...interface{}) Ll1ParserEr
 }
 }
 
 
 
 
-//line ll1.parser.go.tpl:250
+//no-line ll1.parser.go.tpl:250
 func (parser *Ll1Parser) Panicf(message string, args ...interface{})  {
 func (parser *Ll1Parser) Panicf(message string, args ...interface{})  {
     pe := parser.Errorf(message, args...)
     pe := parser.Errorf(message, args...)
     panic(pe)
     panic(pe)
@@ -227,7 +227,7 @@ func (parser *Ll1Parser) Panicf(message string, args ...interface{})  {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:257
+//no-line ll1.parser.go.tpl:257
 func (p *Ll1Parser) Debugf(message string, args ...interface{})  {
 func (p *Ll1Parser) Debugf(message string, args ...interface{})  {
     if p.Debug != nil {
     if p.Debug != nil {
         fmt.Fprintf(p.Debug, message, args)
         fmt.Fprintf(p.Debug, message, args)
@@ -238,7 +238,7 @@ func (p *Ll1Parser) Debugf(message string, args ...interface{})  {
 the token kinds given in kinds. In this case it will return the accepted
 the token kinds given in kinds. In this case it will return the accepted
 token and advance the parser. Otherwise, it will call parser.Panicf.*/
 token and advance the parser. Otherwise, it will call parser.Panicf.*/
 
 
-//line ll1.parser.go.tpl:267
+//no-line ll1.parser.go.tpl:267
 func (parser *Ll1Parser) Require(kinds ...Ll1TokenKind) Ll1Token {
 func (parser *Ll1Parser) Require(kinds ...Ll1TokenKind) Ll1Token {
     parser.Debugf("Require: %v\n", kinds)
     parser.Debugf("Require: %v\n", kinds)
 	if parser.current.Ll1TokenKind == Ll1TokenKind(0) {
 	if parser.current.Ll1TokenKind == Ll1TokenKind(0) {
@@ -260,7 +260,7 @@ func (parser *Ll1Parser) Require(kinds ...Ll1TokenKind) Ll1Token {
 	return Ll1Token{}
 	return Ll1Token{}
 }
 }
 
 
-//line ll1.parser.go.tpl:288
+//no-line ll1.parser.go.tpl:288
 func (parser Ll1Parser) NextIs(kinds ...Ll1TokenKind) bool {
 func (parser Ll1Parser) NextIs(kinds ...Ll1TokenKind) bool {
     parser.Debugf("NextIs: %v\n", kinds)
     parser.Debugf("NextIs: %v\n", kinds)
     if (parser.current.Ll1TokenKind == 0) {
     if (parser.current.Ll1TokenKind == 0) {
@@ -279,203 +279,476 @@ func (parser Ll1Parser) NextIs(kinds ...Ll1TokenKind) bool {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1Grammar struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1Grammar struct {
+    Ll1Token
+    *Ll1Rules
+            
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1Grammar() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1Grammar() (Ll1Grammar, error) {
-    result := Ll1Grammar {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1Grammar() (*Ll1Grammar, error) {
+    var err error
+    result := &Ll1Grammar { Ll1Token: p.current }
+    
+    if p.IsLl1Rules() {
+        result.Ll1Rules, err = p.ParseLl1Rules()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1Rules struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1Rules struct {
+    Ll1Token
+    *Ll1Rule
+            *Ll1OptRules
+            
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1Rules() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1Rules() (Ll1Rules, error) {
-    result := Ll1Rules {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1Rules() (*Ll1Rules, error) {
+    var err error
+    result := &Ll1Rules { Ll1Token: p.current }
+    
+    if p.IsLl1Rule() {
+        result.Ll1Rule, err = p.ParseLl1Rule()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    if p.IsLl1OptRules() {
+        result.Ll1OptRules, err = p.ParseLl1OptRules()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1OptRules struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1OptRules struct {
+    Ll1Token
+    *Ll1Rules
+            
+    
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1OptRules() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1OptRules() (Ll1OptRules, error) {
-    result := Ll1OptRules {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1OptRules() (*Ll1OptRules, error) {
+    var err error
+    result := &Ll1OptRules { Ll1Token: p.current }
+    
+    if p.IsLl1Rules() {
+        result.Ll1Rules, err = p.ParseLl1Rules()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1Rule struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1Rule struct {
+    Ll1Token
+    *Ll1Name
+            *Ll1Definition
+            *Ll1Template
+            
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1Rule() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1Rule() (Ll1Rule, error) {
-    result := Ll1Rule {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1Rule() (*Ll1Rule, error) {
+    var err error
+    result := &Ll1Rule { Ll1Token: p.current }
+    
+    if p.IsLl1Name() {
+        result.Ll1Name, err = p.ParseLl1Name()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    if p.IsLl1Definition() {
+        result.Ll1Definition, err = p.ParseLl1Definition()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    if p.IsLl1Template() {
+        result.Ll1Template, err = p.ParseLl1Template()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1Name struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1Name struct {
+    Ll1Token
+    
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1Name() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1Name() (Ll1Name, error) {
-    result := Ll1Name {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1Name() (*Ll1Name, error) {
+    var err error
+    result := &Ll1Name { Ll1Token: p.current }
+    
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1Template struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1Template struct {
+    Ll1Token
+    
+    
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1Template() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1Template() (Ll1Template, error) {
-    result := Ll1Template {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1Template() (*Ll1Template, error) {
+    var err error
+    result := &Ll1Template { Ll1Token: p.current }
+    
+    
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1Definition struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1Definition struct {
+    Ll1Token
+    *Ll1Alternates
+            
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1Definition() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1Definition() (Ll1Definition, error) {
-    result := Ll1Definition {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1Definition() (*Ll1Definition, error) {
+    var err error
+    result := &Ll1Definition { Ll1Token: p.current }
+    
+    if p.IsLl1Alternates() {
+        result.Ll1Alternates, err = p.ParseLl1Alternates()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1Alternates struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1Alternates struct {
+    Ll1Token
+    *Ll1Sequence
+            *Ll1OptSequences
+            
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1Alternates() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1Alternates() (Ll1Alternates, error) {
-    result := Ll1Alternates {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1Alternates() (*Ll1Alternates, error) {
+    var err error
+    result := &Ll1Alternates { Ll1Token: p.current }
+    
+    if p.IsLl1Sequence() {
+        result.Ll1Sequence, err = p.ParseLl1Sequence()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    if p.IsLl1OptSequences() {
+        result.Ll1OptSequences, err = p.ParseLl1OptSequences()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1OptSequences struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1OptSequences struct {
+    Ll1Token
+    *Ll1Alternates
+            
+    
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1OptSequences() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1OptSequences() (Ll1OptSequences, error) {
-    result := Ll1OptSequences {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1OptSequences() (*Ll1OptSequences, error) {
+    var err error
+    result := &Ll1OptSequences { Ll1Token: p.current }
+    
+    if p.IsLl1Alternates() {
+        result.Ll1Alternates, err = p.ParseLl1Alternates()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1Sequence struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1Sequence struct {
+    Ll1Token
+    *Ll1Element
+            *Ll1OptElements
+            
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1Sequence() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1Sequence() (Ll1Sequence, error) {
-    result := Ll1Sequence {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1Sequence() (*Ll1Sequence, error) {
+    var err error
+    result := &Ll1Sequence { Ll1Token: p.current }
+    
+    if p.IsLl1Element() {
+        result.Ll1Element, err = p.ParseLl1Element()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    if p.IsLl1OptElements() {
+        result.Ll1OptElements, err = p.ParseLl1OptElements()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1OptElements struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1OptElements struct {
+    Ll1Token
+    *Ll1Element
+            *Ll1OptElements
+            
+    
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1OptElements() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1OptElements() (Ll1OptElements, error) {
-    result := Ll1OptElements {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1OptElements() (*Ll1OptElements, error) {
+    var err error
+    result := &Ll1OptElements { Ll1Token: p.current }
+    
+    if p.IsLl1Element() {
+        result.Ll1Element, err = p.ParseLl1Element()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    if p.IsLl1OptElements() {
+        result.Ll1OptElements, err = p.ParseLl1OptElements()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1Element struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1Element struct {
+    Ll1Token
+    *Ll1Parenthesis
+            
+    *Ll1Name
+            
+    
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1Element() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1Element() (Ll1Element, error) {
-    result := Ll1Element {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1Element() (*Ll1Element, error) {
+    var err error
+    result := &Ll1Element { Ll1Token: p.current }
+    
+    if p.IsLl1Parenthesis() {
+        result.Ll1Parenthesis, err = p.ParseLl1Parenthesis()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    
+    if p.IsLl1Name() {
+        result.Ll1Name, err = p.ParseLl1Name()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    
+    return result, err
 }
 }
 
 
 
 
 
 
 
 
 
 
-//line ll1.parser.go.tpl:324
-type Ll1Parenthesis struct {    
-}
+//no-line ll1.parser.go.tpl:324
+type Ll1Parenthesis struct {
+    Ll1Token
+    *Ll1Definition
+            
+    }
 
 
+//no-line ll1.parser.go.tpl:335
+func (p *Ll1Parser) IsLl1Parenthesis() (bool) {
+    return false
+    // return p.NextIs()
+}
 
 
-//line ll1.parser.go.tpl:328
-func ( *Ll1Parser) ParseLl1Parenthesis() (Ll1Parenthesis, error) {
-    result := Ll1Parenthesis {}
-    return result, nil 
+//no-line ll1.parser.go.tpl:340
+func (p *Ll1Parser) ParseLl1Parenthesis() (*Ll1Parenthesis, error) {
+    var err error
+    result := &Ll1Parenthesis { Ll1Token: p.current }
+    
+    if p.IsLl1Definition() {
+        result.Ll1Definition, err = p.ParseLl1Definition()
+        if err != nil {
+            return result, err
+        }
+    }
+            
+    return result, err
 }
 }
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKinddot Ll1TokenKind = Ll1TokenKind(-2)
 const Ll1TokenKinddot Ll1TokenKind = Ll1TokenKind(-2)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKinddot() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKinddot() (Ll1TokenKind, error) {
     result := Ll1TokenKinddot
     result := Ll1TokenKinddot
     return result, nil
     return result, nil
@@ -483,11 +756,11 @@ func ( *Ll1Lexer) LexLl1TokenKinddot() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindor Ll1TokenKind = Ll1TokenKind(-3)
 const Ll1TokenKindor Ll1TokenKind = Ll1TokenKind(-3)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindor() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindor() (Ll1TokenKind, error) {
     result := Ll1TokenKindor
     result := Ll1TokenKindor
     return result, nil
     return result, nil
@@ -495,11 +768,11 @@ func ( *Ll1Lexer) LexLl1TokenKindor() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindidentifier Ll1TokenKind = Ll1TokenKind(-4)
 const Ll1TokenKindidentifier Ll1TokenKind = Ll1TokenKind(-4)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindidentifier() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindidentifier() (Ll1TokenKind, error) {
     result := Ll1TokenKindidentifier
     result := Ll1TokenKindidentifier
     return result, nil
     return result, nil
@@ -507,11 +780,11 @@ func ( *Ll1Lexer) LexLl1TokenKindidentifier() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindruleName Ll1TokenKind = Ll1TokenKind(-5)
 const Ll1TokenKindruleName Ll1TokenKind = Ll1TokenKind(-5)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindruleName() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindruleName() (Ll1TokenKind, error) {
     result := Ll1TokenKindruleName
     result := Ll1TokenKindruleName
     return result, nil
     return result, nil
@@ -519,11 +792,11 @@ func ( *Ll1Lexer) LexLl1TokenKindruleName() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindterminalName Ll1TokenKind = Ll1TokenKind(-6)
 const Ll1TokenKindterminalName Ll1TokenKind = Ll1TokenKind(-6)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindterminalName() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindterminalName() (Ll1TokenKind, error) {
     result := Ll1TokenKindterminalName
     result := Ll1TokenKindterminalName
     return result, nil
     return result, nil
@@ -531,11 +804,11 @@ func ( *Ll1Lexer) LexLl1TokenKindterminalName() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindepsilon Ll1TokenKind = Ll1TokenKind(-7)
 const Ll1TokenKindepsilon Ll1TokenKind = Ll1TokenKind(-7)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindepsilon() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindepsilon() (Ll1TokenKind, error) {
     result := Ll1TokenKindepsilon
     result := Ll1TokenKindepsilon
     return result, nil
     return result, nil
@@ -543,11 +816,11 @@ func ( *Ll1Lexer) LexLl1TokenKindepsilon() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindarrow Ll1TokenKind = Ll1TokenKind(-8)
 const Ll1TokenKindarrow Ll1TokenKind = Ll1TokenKind(-8)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindarrow() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindarrow() (Ll1TokenKind, error) {
     result := Ll1TokenKindarrow
     result := Ll1TokenKindarrow
     return result, nil
     return result, nil
@@ -555,11 +828,11 @@ func ( *Ll1Lexer) LexLl1TokenKindarrow() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindliteral Ll1TokenKind = Ll1TokenKind(-9)
 const Ll1TokenKindliteral Ll1TokenKind = Ll1TokenKind(-9)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindliteral() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindliteral() (Ll1TokenKind, error) {
     result := Ll1TokenKindliteral
     result := Ll1TokenKindliteral
     return result, nil
     return result, nil
@@ -567,11 +840,11 @@ func ( *Ll1Lexer) LexLl1TokenKindliteral() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindstringLiteral Ll1TokenKind = Ll1TokenKind(-10)
 const Ll1TokenKindstringLiteral Ll1TokenKind = Ll1TokenKind(-10)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindstringLiteral() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindstringLiteral() (Ll1TokenKind, error) {
     result := Ll1TokenKindstringLiteral
     result := Ll1TokenKindstringLiteral
     return result, nil
     return result, nil
@@ -579,11 +852,11 @@ func ( *Ll1Lexer) LexLl1TokenKindstringLiteral() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindcharLiteral Ll1TokenKind = Ll1TokenKind(-11)
 const Ll1TokenKindcharLiteral Ll1TokenKind = Ll1TokenKind(-11)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindcharLiteral() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindcharLiteral() (Ll1TokenKind, error) {
     result := Ll1TokenKindcharLiteral
     result := Ll1TokenKindcharLiteral
     return result, nil
     return result, nil
@@ -591,11 +864,11 @@ func ( *Ll1Lexer) LexLl1TokenKindcharLiteral() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindrawString Ll1TokenKind = Ll1TokenKind(-12)
 const Ll1TokenKindrawString Ll1TokenKind = Ll1TokenKind(-12)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindrawString() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindrawString() (Ll1TokenKind, error) {
     result := Ll1TokenKindrawString
     result := Ll1TokenKindrawString
     return result, nil
     return result, nil
@@ -603,11 +876,11 @@ func ( *Ll1Lexer) LexLl1TokenKindrawString() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindwhiteSpace Ll1TokenKind = Ll1TokenKind(-13)
 const Ll1TokenKindwhiteSpace Ll1TokenKind = Ll1TokenKind(-13)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindwhiteSpace() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindwhiteSpace() (Ll1TokenKind, error) {
     result := Ll1TokenKindwhiteSpace
     result := Ll1TokenKindwhiteSpace
     return result, nil
     return result, nil
@@ -615,11 +888,11 @@ func ( *Ll1Lexer) LexLl1TokenKindwhiteSpace() (Ll1TokenKind, error) {
 
 
 
 
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindlineComment Ll1TokenKind = Ll1TokenKind(-14)
 const Ll1TokenKindlineComment Ll1TokenKind = Ll1TokenKind(-14)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindlineComment() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindlineComment() (Ll1TokenKind, error) {
     result := Ll1TokenKindlineComment
     result := Ll1TokenKindlineComment
     return result, nil
     return result, nil
@@ -632,11 +905,11 @@ func ( *Ll1Lexer) LexLl1TokenKindlineComment() (Ll1TokenKind, error) {
 
 
 // Not implemented
 // Not implemented
 
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindhandCoded Ll1TokenKind = Ll1TokenKind(-15)
 const Ll1TokenKindhandCoded Ll1TokenKind = Ll1TokenKind(-15)
 
 
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindhandCoded() (Ll1TokenKind, error) {
 func ( *Ll1Lexer) LexLl1TokenKindhandCoded() (Ll1TokenKind, error) {
     result := Ll1TokenKindhandCoded
     result := Ll1TokenKindhandCoded
     return result, nil
     return result, nil

+ 138 - 0
parser.go

@@ -6,6 +6,140 @@ import "io"
 import "os"
 import "os"
 import "unicode"
 import "unicode"
 
 
+
+// Value  is the lexical value of a lexer token. 
+// This is an alias for string in the case of ll1.
+type Value = string
+
+
+// Position is a position within a source file. Since the lexer is based on 
+// text/scanner, we use that packages Position.
+type Position = scanner.Position
+
+// TokenKind is the kind or type of a token.
+// This has rune as the underlying type so one-character tokens can be easily 
+// supported. EOF will be 65535 (I.e, -1 cast to rune). Non-character token 
+// kinds will start from 65533 down (i.e -3, -4, -5, etc).
+type TokenKind rune
+
+
+// NoTokenKind means "no token kind" i.e. no token. 
+const NoTokenKind TokenKind = TokenKind(0)
+
+// TokenKindEOF means the end of the input. 
+const TokenKindEOF TokenKind = TokenKind(scanner.EOF)
+
+// TokenKindError means a parsing or lexing error was encountered. 
+//line ll1.parser.go.tpl:80
+const TokenKindError TokenKind = TokenKind(-21)
+
+
+// Scanner based token kinds
+const TokenKindIdent      TokenKind = TokenKind(scanner.Ident    )
+const TokenKindInt        TokenKind = TokenKind(scanner.Int      )
+const TokenKindFloat      TokenKind = TokenKind(scanner.Float    )
+const TokenKindChar       TokenKind = TokenKind(scanner.Char     )
+const TokenKindString     TokenKind = TokenKind(scanner.String   )
+const TokenKindRawString  TokenKind = TokenKind(scanner.RawString)
+const TokenKindComment    TokenKind = TokenKind(scanner.Comment  )
+
+// Grammar based token kinds
+const (
+    TokenKindEpsilon    TokenKind = TokenKind('ε')
+    TokenKindOr         TokenKind = TokenKind('|')
+    TokenKindArrow      TokenKind = TokenKind('→')
+    TokenKindStar       TokenKind = TokenKind('*')
+    TokenKindOptional   TokenKind = TokenKind('?')
+    TokenKindList       TokenKind = TokenKind('+')
+    TokenKindRuleEnd    TokenKind = TokenKind('.')
+)
+
+
+// Convert token kind to a string representation
+
+//line ll1.parser.go.tpl:86
+func (tk TokenKind) String() string {
+    
+        return scanner.TokenString(rune(tk))
+    
+}
+
+
+// Token is the result of a single lexical analysis step by the lexer.
+
+//line ll1.parser.go.tpl:109
+type Token struct {
+	Position   // Position in the source where the token was found.
+	TokenKind  // Type of the token
+	Value      // Value of the token
+}
+
+
+// MakeToken makes a token with the given position, type and value.
+
+//line ll1.parser.go.tpl:118
+func MakeToken(pos Position, typ TokenKind, val Value) Token {
+    return Token{ pos, typ, val}
+}
+
+// Lexer performs the lexical analysis of the input.
+
+//line ll1.parser.go.tpl:124
+type Lexer struct {
+    // Embed scanner.Scanner
+    scanner.Scanner
+    Filename string    
+}
+
+
+// NewLexerFromReader creates a new lexer for the given parser and input.
+
+//line ll1.parser.go.tpl:133
+func NewLexerFromReader(parser *Parser, reader io.Reader, filename string) *Lexer {
+    lexer := &Lexer{}
+    lexer.Filename = filename
+    lexer.Scanner.Init(reader)
+    lexer.Scanner.Mode = scanner.GoTokens
+    lexer.Scanner.Error = func (s *scanner.Scanner, msg string) {
+        parser.Panicf("%s: scanner error: %s, %s", s.Position, s.TokenText(), msg)
+    }
+    // XXX: needs to be generated from the identifier rule in the syntax!
+    lexer.Scanner.IsIdentRune = func(ch rune, i int) bool {
+        if i == 0 {
+            return unicode.IsLetter(ch)
+        }    
+        return unicode.IsLetter(ch) || 
+               unicode.IsNumber(ch) || 
+                          ch == '_' || 
+                          ch == '-'
+    }
+    return lexer
+}
+
+
+//line ll1.parser.go.tpl:155
+func (lex *Lexer) Lex() Token {
+    scanned := lex.Scanner.Scan()
+    pos := lex.Scanner.Position
+    pos.Filename = lex.Filename    
+    value := lex.Scanner.TokenText()
+    // Get rid of the quotes
+    if scanned == scanner.Char || 
+       scanned == scanner.String || 
+       scanned == scanner.RawString {
+           value = value[1:len(value) - 1]
+    }
+    token := Token { 
+        TokenKind: TokenKind(scanned), 
+        Value: value, 
+        Position: pos,
+    }
+    return token
+}
+
+
+
+
 // This parser is for parsing LL1 grammars, not Beo. 
 // This parser is for parsing LL1 grammars, not Beo. 
 type Parser struct {
 type Parser struct {
     reader io.Reader
     reader io.Reader
@@ -149,6 +283,10 @@ func (p *Parser) NextIsElement() (bool) {
     return p.NextIs('(', scanner.Ident, scanner.Char, scanner.String)
     return p.NextIs('(', scanner.Ident, scanner.Char, scanner.String)
 }
 }
 
 
+func (p *Parser) NextIsOperator() (bool) {
+    return p.NextIs('+', '*')
+}
+
 func (p *Parser) ParseElement() (Element, error) {      
 func (p *Parser) ParseElement() (Element, error) {      
     switch {
     switch {
         case p.NextIs('('):
         case p.NextIs('('):

+ 2 - 0
template_functions.go

@@ -198,6 +198,8 @@ var templateFunctionMap template.FuncMap = template.FuncMap{
 	"IndexByte":            strings.IndexByte,
 	"IndexByte":            strings.IndexByte,
 	"IndexFunc":            strings.IndexFunc,
 	"IndexFunc":            strings.IndexFunc,
 	"IndexRune":            strings.IndexRune,
 	"IndexRune":            strings.IndexRune,
+    "IsEpsilon":            IsEpsilon,
+    "IsNonterminal":        IsNonterminal,
 	"Join":                 strings.Join,
 	"Join":                 strings.Join,
 	"LastIndex":            strings.LastIndex,
 	"LastIndex":            strings.LastIndex,
 	"LastIndexAny":         strings.LastIndexAny,
 	"LastIndexAny":         strings.LastIndexAny,