// We can't specify the namespace in yacc's C output, so do it here instead.
using namespace JSC;
-#ifndef KDE_USE_FINAL
#include "Grammar.h"
-#endif
-
#include "Lookup.h"
#include "Lexer.lut.h"
-// A bridge for yacc from the C world to the C++ world.
-int jscyylex(void* lvalp, void* llocp, void* globalData)
-{
- return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp);
-}
-
namespace JSC {
static const UChar byteOrderMark = 0xFEFF;
m_code += 4;
}
-void Lexer::setCode(const SourceCode& source)
+void Lexer::setCode(const SourceCode& source, ParserArena& arena)
{
+ m_arena = &arena.identifierArena();
+
m_lineNumber = source.firstLine();
m_delimited = false;
m_lastToken = -1;
++m_lineNumber;
}
-ALWAYS_INLINE Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length)
+ALWAYS_INLINE const Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length)
{
- m_identifiers.append(Identifier(m_globalData, characters, length));
- return &m_identifiers.last();
+ return &m_arena->makeIdentifier(m_globalData, characters, length);
}
inline bool Lexer::lastTokenWasRestrKeyword() const
shiftLineTerminator();
goto inString;
}
+ if (m_current == -1)
+ goto returnError;
record16(singleEscape(m_current));
shift1();
goto inString;
return -1;
}
-bool Lexer::scanRegExp()
+bool Lexer::scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix)
{
ASSERT(m_buffer16.isEmpty());
bool lastWasEscape = false;
bool inBrackets = false;
+ if (patternPrefix) {
+ ASSERT(!isLineTerminator(patternPrefix));
+ ASSERT(patternPrefix != '/');
+ ASSERT(patternPrefix != '[');
+ record16(patternPrefix);
+ }
+
while (true) {
- if (isLineTerminator(m_current) || m_current == -1)
- return false;
- if (m_current != '/' || lastWasEscape || inBrackets) {
- // keep track of '[' and ']'
- if (!lastWasEscape) {
- if (m_current == '[' && !inBrackets)
- inBrackets = true;
- if (m_current == ']' && inBrackets)
- inBrackets = false;
- }
- record16(m_current);
- lastWasEscape = !lastWasEscape && m_current == '\\';
- } else { // end of regexp
- m_pattern = UString(m_buffer16);
+ int current = m_current;
+
+ if (isLineTerminator(current) || current == -1) {
m_buffer16.resize(0);
- shift1();
- break;
+ return false;
}
+
shift1();
+
+ if (current == '/' && !lastWasEscape && !inBrackets)
+ break;
+
+ record16(current);
+
+ if (lastWasEscape) {
+ lastWasEscape = false;
+ continue;
+ }
+
+ switch (current) {
+ case '[':
+ inBrackets = true;
+ break;
+ case ']':
+ inBrackets = false;
+ break;
+ case '\\':
+ lastWasEscape = true;
+ break;
+ }
}
+ pattern = makeIdentifier(m_buffer16.data(), m_buffer16.size());
+ m_buffer16.resize(0);
+
while (isIdentPart(m_current)) {
record16(m_current);
shift1();
}
- m_flags = UString(m_buffer16);
+
+ flags = makeIdentifier(m_buffer16.data(), m_buffer16.size());
m_buffer16.resize(0);
return true;
}
+bool Lexer::skipRegExp()
+{
+ bool lastWasEscape = false;
+ bool inBrackets = false;
+
+ while (true) {
+ int current = m_current;
+
+ if (isLineTerminator(current) || current == -1)
+ return false;
+
+ shift1();
+
+ if (current == '/' && !lastWasEscape && !inBrackets)
+ break;
+
+ if (lastWasEscape) {
+ lastWasEscape = false;
+ continue;
+ }
+
+ switch (current) {
+ case '[':
+ inBrackets = true;
+ break;
+ case ']':
+ inBrackets = false;
+ break;
+ case '\\':
+ lastWasEscape = true;
+ break;
+ }
+ }
+
+ while (isIdentPart(m_current))
+ shift1();
+
+ return true;
+}
+
void Lexer::clear()
{
- m_identifiers.clear();
+ m_arena = 0;
m_codeWithoutBOMs.clear();
Vector<char> newBuffer8;
m_buffer16.swap(newBuffer16);
m_isReparsing = false;
-
- m_pattern = UString();
- m_flags = UString();
}
SourceCode Lexer::sourceCode(int openBrace, int closeBrace, int firstLine)