|
|
|
@ -0,0 +1,58 @@ |
|
|
|
package parser |
|
|
|
|
|
|
|
import ( |
|
|
|
"io" |
|
|
|
|
|
|
|
"github.com/brettlangdon/gython/ast" |
|
|
|
"github.com/brettlangdon/gython/errorcode" |
|
|
|
"github.com/brettlangdon/gython/scanner" |
|
|
|
"github.com/brettlangdon/gython/token" |
|
|
|
) |
|
|
|
|
|
|
|
type Parser struct { |
|
|
|
tokenizer *scanner.Scanner |
|
|
|
|
|
|
|
tokenBuffer []*token.Token |
|
|
|
} |
|
|
|
|
|
|
|
func (parser *Parser) nextToken() *token.Token { |
|
|
|
if len(parser.tokenBuffer) > 0 { |
|
|
|
last := len(parser.tokenBuffer) - 1 |
|
|
|
next := parser.tokenBuffer[last] |
|
|
|
parser.tokenBuffer = parser.tokenBuffer[:last] |
|
|
|
return next |
|
|
|
} |
|
|
|
|
|
|
|
return parser.tokenizer.NextToken() |
|
|
|
} |
|
|
|
|
|
|
|
func (parser *Parser) unreadToken(tok *token.Token) { |
|
|
|
parser.tokenBuffer = append(parser.tokenBuffer, tok) |
|
|
|
} |
|
|
|
|
|
|
|
func (parser *Parser) parseFileInput() *ast.FileInput { |
|
|
|
root := ast.NewFileInput() |
|
|
|
for parser.tokenizer.State() == errorcode.E_OK { |
|
|
|
next := parser.nextToken() |
|
|
|
if next.ID == token.NEWLINE { |
|
|
|
root.AppendToken(next) |
|
|
|
} else if next.ID == token.ENDMARKER { |
|
|
|
break |
|
|
|
} else { |
|
|
|
parser.unreadToken(next) |
|
|
|
// TODO: parser.parseStatement()
|
|
|
|
break |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return root |
|
|
|
} |
|
|
|
|
|
|
|
func ParseReader(r io.Reader) *ast.FileInput { |
|
|
|
parser := &Parser{ |
|
|
|
tokenizer: scanner.NewScanner(r), |
|
|
|
tokenBuffer: make([]*token.Token, 0), |
|
|
|
} |
|
|
|
|
|
|
|
return parser.parseFileInput() |
|
|
|
} |