| @ -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() | |||||
| } | |||||