Browse Source

Commit old stuff before restarting on new branch.

Beoran 2 years ago
parent
commit
ed36a5761c
6 changed files with 638 additions and 153 deletions
  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 .
 Definition -> Alternates . // Alternates have a higher priority than sequences.
 Alternates -> Sequence or Alternates | .
-Sequence -> Element Sequence | . 
+Sequence -> Element Sequence | Operator Sequence | . 
+Operator -> plus Element | star Element .
 Element -> Parenthesis | Terminal | Literal .
 Parenthesis -> '(' Definition ')' .
 Terminal -> identifier .
@@ -305,6 +306,24 @@ func (s Set) String() string {
     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,
 // where alternates can contain sequences and parenthesis.
 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) }}
 
 //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}}
 

+ 31 - 5
ll1.parser.go.tpl

@@ -307,7 +307,7 @@ func (parser {{$Parser}}) NextIs(kinds ...{{$TokenKind}}) bool {
 {{ .Template }}
 {{ end }}
 {{- $terminal := .IsTerminal -}}
-{{- if $terminal -}}
+{{- if $  -}}
 {{- $TokenKindName := ( printf "%s%s" $TokenKind $ruleName) -}}
 
 const {{$TokenKindName}} {{$TokenKind}} = {{$TokenKind}}(-{{$tokenKindValue}})
@@ -321,13 +321,39 @@ func ( *{{$Lexer}}) Lex{{$TokenKindName}}() ({{$TokenKind}}, error) {
 {{ else }}
 {{ $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}}
 

+ 415 - 142
ll1_parser.go

@@ -1,6 +1,6 @@
 /* 
  * 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
  * Uses a scanner
  * 
@@ -25,7 +25,7 @@ import "fmt"
 
 // This is based on strings as a default.
 
-//line ll1.parser.go.tpl:43
+//no-line ll1.parser.go.tpl:43
 type Ll1Value = string
 
 
@@ -34,7 +34,7 @@ type Ll1Value = string
 // Ll1Position is a position within a source file. Since the lexer is based on 
 // 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
 
 
@@ -44,28 +44,28 @@ type Ll1Position = scanner.Position
 // 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).
 
-//line ll1.parser.go.tpl:69
+//no-line ll1.parser.go.tpl:69
 type Ll1TokenKind rune
 
 
 // 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)
 // 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)
 // 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)
 
 
 
 // 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 {
     
         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.
 
-//line ll1.parser.go.tpl:109
+//no-line ll1.parser.go.tpl:109
 type Ll1Token struct {
 	Ll1Position   // Position in the source where the token was found.
 	Ll1TokenKind  // Type of the token
@@ -85,14 +85,14 @@ type Ll1Token struct {
 
 // 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 {
     return Ll1Token{ pos, typ, val}
 }
 
 // Ll1Lexer performs the lexical analysis of the input.
 
-//line ll1.parser.go.tpl:124
+//no-line ll1.parser.go.tpl:124
 type Ll1Lexer struct {
     // Embed scanner.Scanner
     scanner.Scanner
@@ -102,7 +102,7 @@ type Ll1Lexer struct {
 
 // 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 {
     lexer := &Ll1Lexer{}
     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 {
     scanned := lex.Scanner.Scan()
     pos := lex.Scanner.Position
@@ -151,7 +151,7 @@ func (lex *Ll1Lexer) Lex() Ll1Token {
 // Ll1Parser parses the input and returns a parse tree, 
 // based on the rules in ll1.ll1
 
-//line ll1.parser.go.tpl:188
+//no-line ll1.parser.go.tpl:188
 type Ll1Parser struct {
     reader io.Reader
     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 {
     parser := &Ll1Parser{}
     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.
 
-//line ll1.parser.go.tpl:214
+//no-line ll1.parser.go.tpl:214
 func (p *Ll1Parser) Advance() Ll1Token {
 	token := p.lexer.Lex()
     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 
 // from making progress.
 
-//line ll1.parser.go.tpl:225
+//no-line ll1.parser.go.tpl:225
 type Ll1ParserError struct {
     *Ll1Parser // Parser that had the error.
     *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 {
     // XXX will need to be improved
 	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 {
 	err := fmt.Errorf(message, args...)
     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{})  {
     pe := parser.Errorf(message, args...)
     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{})  {
     if p.Debug != nil {
         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
 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 {
     parser.Debugf("Require: %v\n", kinds)
 	if parser.current.Ll1TokenKind == Ll1TokenKind(0) {
@@ -260,7 +260,7 @@ func (parser *Ll1Parser) Require(kinds ...Ll1TokenKind) Ll1Token {
 	return Ll1Token{}
 }
 
-//line ll1.parser.go.tpl:288
+//no-line ll1.parser.go.tpl:288
 func (parser Ll1Parser) NextIs(kinds ...Ll1TokenKind) bool {
     parser.Debugf("NextIs: %v\n", kinds)
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKinddot() (Ll1TokenKind, error) {
     result := Ll1TokenKinddot
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindor() (Ll1TokenKind, error) {
     result := Ll1TokenKindor
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindidentifier() (Ll1TokenKind, error) {
     result := Ll1TokenKindidentifier
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindruleName() (Ll1TokenKind, error) {
     result := Ll1TokenKindruleName
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindterminalName() (Ll1TokenKind, error) {
     result := Ll1TokenKindterminalName
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindepsilon() (Ll1TokenKind, error) {
     result := Ll1TokenKindepsilon
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindarrow() (Ll1TokenKind, error) {
     result := Ll1TokenKindarrow
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindliteral() (Ll1TokenKind, error) {
     result := Ll1TokenKindliteral
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindstringLiteral() (Ll1TokenKind, error) {
     result := Ll1TokenKindstringLiteral
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindcharLiteral() (Ll1TokenKind, error) {
     result := Ll1TokenKindcharLiteral
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindrawString() (Ll1TokenKind, error) {
     result := Ll1TokenKindrawString
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindwhiteSpace() (Ll1TokenKind, error) {
     result := Ll1TokenKindwhiteSpace
     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)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindlineComment() (Ll1TokenKind, error) {
     result := Ll1TokenKindlineComment
     return result, nil
@@ -632,11 +905,11 @@ func ( *Ll1Lexer) LexLl1TokenKindlineComment() (Ll1TokenKind, error) {
 
 // Not implemented
 
-//line ll1.parser.go.tpl:313
+//no-line ll1.parser.go.tpl:313
 const Ll1TokenKindhandCoded Ll1TokenKind = Ll1TokenKind(-15)
 
 
-//line ll1.parser.go.tpl:316
+//no-line ll1.parser.go.tpl:316
 func ( *Ll1Lexer) LexLl1TokenKindhandCoded() (Ll1TokenKind, error) {
     result := Ll1TokenKindhandCoded
     return result, nil

+ 138 - 0
parser.go

@@ -6,6 +6,140 @@ import "io"
 import "os"
 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. 
 type Parser struct {
     reader io.Reader
@@ -149,6 +283,10 @@ func (p *Parser) NextIsElement() (bool) {
     return p.NextIs('(', scanner.Ident, scanner.Char, scanner.String)
 }
 
+func (p *Parser) NextIsOperator() (bool) {
+    return p.NextIs('+', '*')
+}
+
 func (p *Parser) ParseElement() (Element, error) {      
     switch {
         case p.NextIs('('):

+ 2 - 0
template_functions.go

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