/// Parse returns the fully parsed source and returns the abstract syntax tree. public File Parse() { var f = new File(); Exception scerr = null; sc.Error = (pos, msg) => { scerr = new PosErrorException(pos, msg); }; f.Node = this.ObjectList(false); if (scerr != null) { throw scerr; } f.Comments = comments; return(f); }
/// objectKey parses an object key and returns a ObjectKey AST public slice <ObjectKey> ObjectKey() { var keyCount = 0; var keys = slice.Make <ObjectKey>(0); for (;;) { var tok = Scan(); switch (tok.Type) { case TokenType.EOF: // It is very important to also return the keys here as well as // the error. This is because we need to be able to tell if we // did parse keys prior to finding the EOF, or if we just found // a bare EOF. //return keys, errEofToken throw new ErrEofTokenException(keys); case TokenType.ASSIGN: // assignment or object only, but not nested objects. this is not // allowed: `foo bar = {}` if (keyCount > 1) { throw new PosErrorException(tok.Pos, $"nested object expected: LBRACE got: {tok.Type}"); } if (keyCount == 0) { throw new PosErrorException(tok.Pos, "no object keys found!"); } return(keys); case TokenType.LBRACE: Exception err = null; // If we have no keys, then it is a syntax error. i.e. {{}} is not // allowed. if (keys.Length == 0) { err = new PosErrorException(tok.Pos, $"expected: IDENT | STRING got: {tok.Type}", keys: keys); // err = &PosError{ // Pos: p.tok.Pos, // Err: fmt.Errorf("expected: IDENT | STRING got: %s", p.tok.Type), // } throw err; } // object //return keys, err return(keys); case TokenType.IDENT: keyCount++; keys = keys.Append(new ObjectKey { Token = tok }); break; case TokenType.STRING: keyCount++; keys = keys.Append(new ObjectKey { Token = tok }); break; case TokenType.ILLEGAL: // return keys, &PosError{ // Pos: p.tok.Pos, // Err: fmt.Errorf("illegal character"), // } throw new PosErrorException(tok.Pos, "illegal character", keys: keys); default: // return keys, &PosError{ // Pos: p.tok.Pos, // Err: fmt.Errorf("expected: IDENT | STRING | ASSIGN | LBRACE got: %s", p.tok.Type), // } throw new PosErrorException(tok.Pos, $"expected: IDENT | STRING | ASSIGN | LBRACE got: {tok.Type}", keys: keys); } } }
public void TestPosError_impl() { var err = new PosErrorException(new token.Pos(), string.Empty); }