1 | // -*- c-basic-offset: 4 -*-
|
---|
2 | /*
|
---|
3 | * This file is part of the KDE libraries
|
---|
4 | * Copyright (C) 1999-2001 Harri Porten ([email protected])
|
---|
5 | * Copyright (C) 2001 Peter Kelly ([email protected])
|
---|
6 | * Copyright (C) 2003, 2006 Apple Computer, Inc.
|
---|
7 | *
|
---|
8 | * This library is free software; you can redistribute it and/or
|
---|
9 | * modify it under the terms of the GNU Library General Public
|
---|
10 | * License as published by the Free Software Foundation; either
|
---|
11 | * version 2 of the License, or (at your option) any later version.
|
---|
12 | *
|
---|
13 | * This library is distributed in the hope that it will be useful,
|
---|
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
16 | * Library General Public License for more details.
|
---|
17 | *
|
---|
18 | * You should have received a copy of the GNU Library General Public License
|
---|
19 | * along with this library; see the file COPYING.LIB. If not, write to
|
---|
20 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
---|
21 | * Boston, MA 02110-1301, USA.
|
---|
22 | *
|
---|
23 | */
|
---|
24 |
|
---|
25 | #include "config.h"
|
---|
26 | #include "Parser.h"
|
---|
27 |
|
---|
28 | #include "lexer.h"
|
---|
29 | #include "nodes.h"
|
---|
30 | #include <wtf/HashSet.h>
|
---|
31 | #include <wtf/Vector.h>
|
---|
32 |
|
---|
33 | extern int kjsyyparse();
|
---|
34 |
|
---|
35 | namespace KJS {
|
---|
36 |
|
---|
37 | int Parser::sid = 0;
|
---|
38 |
|
---|
39 | static RefPtr<ProgramNode>* progNode;
|
---|
40 | static HashSet<Node*>* nodeCycles;
|
---|
41 |
|
---|
42 | void Parser::noteNodeCycle(Node *node)
|
---|
43 | {
|
---|
44 | if (!nodeCycles)
|
---|
45 | nodeCycles = new HashSet<Node*>;
|
---|
46 | nodeCycles->add(node);
|
---|
47 | }
|
---|
48 |
|
---|
49 | void Parser::removeNodeCycle(Node *node)
|
---|
50 | {
|
---|
51 | ASSERT(nodeCycles);
|
---|
52 | nodeCycles->remove(node);
|
---|
53 | }
|
---|
54 |
|
---|
55 | static void clearNewNodes()
|
---|
56 | {
|
---|
57 | if (nodeCycles) {
|
---|
58 | for (HashSet<Node*>::iterator it = nodeCycles->begin(); it != nodeCycles->end(); ++it)
|
---|
59 | (*it)->breakCycle();
|
---|
60 | delete nodeCycles;
|
---|
61 | nodeCycles = 0;
|
---|
62 | }
|
---|
63 | Node::clearNewNodes();
|
---|
64 | }
|
---|
65 |
|
---|
66 | PassRefPtr<ProgramNode> Parser::parse(const UString& sourceURL, int startingLineNumber,
|
---|
67 | const UChar* code, unsigned length,
|
---|
68 | int* sourceId, int* errLine, UString* errMsg)
|
---|
69 | {
|
---|
70 | if (errLine)
|
---|
71 | *errLine = -1;
|
---|
72 | if (errMsg)
|
---|
73 | *errMsg = 0;
|
---|
74 | if (!progNode)
|
---|
75 | progNode = new RefPtr<ProgramNode>;
|
---|
76 |
|
---|
77 | Lexer::curr()->setCode(sourceURL, startingLineNumber, code, length);
|
---|
78 | *progNode = 0;
|
---|
79 | sid++;
|
---|
80 | if (sourceId)
|
---|
81 | *sourceId = sid;
|
---|
82 |
|
---|
83 | // Enable this and the #define YYDEBUG in grammar.y to debug a parse error
|
---|
84 | //extern int kjsyydebug;
|
---|
85 | //kjsyydebug=1;
|
---|
86 |
|
---|
87 | int parseError = kjsyyparse();
|
---|
88 | bool lexError = Lexer::curr()->sawError();
|
---|
89 | Lexer::curr()->doneParsing();
|
---|
90 | PassRefPtr<ProgramNode> prog = progNode->release();
|
---|
91 | *progNode = 0;
|
---|
92 |
|
---|
93 | clearNewNodes();
|
---|
94 |
|
---|
95 | if (parseError || lexError) {
|
---|
96 | int eline = Lexer::curr()->lineNo();
|
---|
97 | if (errLine)
|
---|
98 | *errLine = eline;
|
---|
99 | if (errMsg)
|
---|
100 | *errMsg = "Parse error";
|
---|
101 | return 0;
|
---|
102 | }
|
---|
103 |
|
---|
104 | return prog;
|
---|
105 | }
|
---|
106 |
|
---|
107 | void Parser::accept(PassRefPtr<ProgramNode> prog)
|
---|
108 | {
|
---|
109 | *progNode = prog;
|
---|
110 | }
|
---|
111 |
|
---|
112 | UString Parser::prettyPrint(const UString& code, int* errLine, UString* errMsg)
|
---|
113 | {
|
---|
114 | RefPtr<ProgramNode> progNode = parse(UString(), 0, code.data(), code.size(), 0, errLine, errMsg);
|
---|
115 | if (!progNode)
|
---|
116 | return 0;
|
---|
117 |
|
---|
118 | return progNode->toString();
|
---|
119 | }
|
---|
120 |
|
---|
121 | }
|
---|