6 Lexer::Lexer(const std::string
& input
)
8 m_data
= strncopy(input
.c_str(), input
.size());
11 m_dataEnd
= int(input
.size());
15 Lexer::Lexer(Lexer
* owner
, int startChar
, int endChar
)
17 m_data
= owner
->m_data
;
19 m_dataStart
= startChar
;
34 m_dataPos
= m_dataStart
;
45 void Lexer::match(int expected_tk
)
47 if(m_tk
!= expected_tk
)
49 std::stringstream errorString
;
50 errorString
<< "Got " << getTokenStr(m_tk
) << " expected " << getTokenStr(expected_tk
)
51 << " at " << getPosition(m_tokenStart
);
52 throw new RuntimeError(errorString
.str());
57 std::string
Lexer::getTokenStr(int token
)
59 if((token
> 32) && (token
< 128))
89 case LEX_LSHIFTEQUAL
:
95 case LEX_RSHIFTUNSIGNED
:
97 case LEX_RSHIFTEQUAL
:
101 case LEX_MINUSEQUAL
:
105 case LEX_MINUSMINUS
:
130 case LEX_R_CONTINUE
:
132 case LEX_R_FUNCTION
:
144 case LEX_R_UNDEFINED
:
149 std::stringstream msg
;
150 msg
<< "?[" << token
<< "]";
154 void Lexer::getNextCh()
157 if(m_dataPos
< m_dataEnd
)
159 m_nextCh
= m_data
[m_dataPos
];
168 void Lexer::getNextToken()
172 while(m_currCh
&& isWhitespace(m_currCh
))
177 if((m_currCh
== '/') && (m_nextCh
== '/'))
179 while(m_currCh
&& (m_currCh
!= '\n'))
188 if((m_currCh
== '/') && (m_nextCh
== '*'))
190 while(m_currCh
&& ((m_currCh
!= '*') || (m_nextCh
!= '/')))
199 // record beginning of this token
200 m_tokenStart
= (m_dataPos
- 2);
202 if(isAlpha(m_currCh
)) // IDs
204 while(isAlpha(m_currCh
) || isNumeric(m_currCh
))
214 else if(m_tkStr
== "else")
218 else if(m_tkStr
== "do")
222 else if(m_tkStr
== "while")
226 else if(m_tkStr
== "for")
230 else if(m_tkStr
== "break")
234 else if(m_tkStr
== "continue")
236 m_tk
= LEX_R_CONTINUE
;
238 else if(m_tkStr
== "function")
240 m_tk
= LEX_R_FUNCTION
;
242 else if(m_tkStr
== "return")
246 else if(m_tkStr
== "var")
250 else if(m_tkStr
== "true")
254 else if(m_tkStr
== "false")
258 else if(m_tkStr
== "null")
262 else if(m_tkStr
== "undefined")
264 m_tk
= LEX_R_UNDEFINED
;
266 else if(m_tkStr
== "new")
271 else if(isNumeric(m_currCh
)) // Numbers
286 while(isNumeric(m_currCh
) || (isHex
&& isHexadecimal(m_currCh
)))
291 if(!isHex
&& (m_currCh
== '.'))
296 while(isNumeric(m_currCh
))
302 // do fancy e-style floating point
303 if(!isHex
&& ((m_currCh
== 'e') || (m_currCh
== 'E')))
313 while(isNumeric(m_currCh
))
320 else if(m_currCh
== '"')
324 while(m_currCh
&& (m_currCh
!= '"'))
353 else if(m_currCh
== '\'')
357 while(m_currCh
&& (m_currCh
!= '\''))
382 case 'x' : // hex digits
389 m_tkStr
+= (char)strtol(buf
,0,16);
393 if((m_currCh
>= '0') && (m_currCh
<= '7'))
402 m_tkStr
+= (char)strtol(buf
,0,8);
427 if((m_tk
== '=') && (m_currCh
== '=')) // ==
431 if(m_currCh
== '=') // ===
433 m_tk
= LEX_TYPEEQUAL
;
437 else if((m_tk
== '!') && (m_currCh
== '=')) // !=
441 if(m_currCh
== '=') // !==
443 m_tk
= LEX_NTYPEEQUAL
;
447 else if((m_tk
== '<') && (m_currCh
== '='))
452 else if((m_tk
== '<') && (m_currCh
== '<'))
456 if(m_currCh
== '=') // <<=
458 m_tk
= LEX_LSHIFTEQUAL
;
462 else if((m_tk
== '>') && (m_currCh
== '='))
467 else if((m_tk
== '>') && (m_currCh
== '>'))
471 if(m_currCh
== '=') // >>=
473 m_tk
= LEX_RSHIFTEQUAL
;
476 else if(m_currCh
== '>') // >>>
478 m_tk
= LEX_RSHIFTUNSIGNED
;
482 else if((m_tk
== '+') && (m_currCh
== '='))
484 m_tk
= LEX_PLUSEQUAL
;
487 else if((m_tk
== '-') && (m_currCh
== '='))
489 m_tk
= LEX_MINUSEQUAL
;
492 else if((m_tk
== '+') && (m_currCh
== '+'))
497 else if((m_tk
== '-') && (m_currCh
== '-'))
499 m_tk
= LEX_MINUSMINUS
;
502 else if((m_tk
== '&') && (m_currCh
== '='))
507 else if((m_tk
== '&') && (m_currCh
== '&'))
512 else if((m_tk
== '|') && (m_currCh
== '='))
517 else if((m_tk
== '|') && (m_currCh
== '|'))
522 else if((m_tk
== '^') && (m_currCh
== '='))
528 /* This isn't quite right yet */
529 m_tokenLastEnd
= m_tokenEnd
;
530 m_tokenEnd
= (m_dataPos
- 3);
533 std::string
Lexer::getSubString(int lastPosition
)
535 int lastCharIdx
= (m_tokenLastEnd
+ 1);
536 if(lastCharIdx
< m_dataEnd
)
538 /* save a memory alloc by using our data array to create the string */
539 char old
= m_data
[lastCharIdx
];
540 m_data
[lastCharIdx
] = 0;
541 std::string value
= &m_data
[lastPosition
];
542 m_data
[lastCharIdx
] = old
;
547 return std::string(&m_data
[lastPosition
]);
551 Lexer
* Lexer::getSubLex(int lastPosition
)
553 int lastCharIdx
= (m_tokenLastEnd
+ 1);
554 if(lastCharIdx
< m_dataEnd
)
556 return new Lexer(this, lastPosition
, lastCharIdx
);
560 return new Lexer(this, lastPosition
, m_dataEnd
);
564 std::string
Lexer::getPosition(int pos
)
570 pos
= m_tokenLastEnd
;
574 for(int i
=0; i
<pos
; i
++)
593 sprintf_s(buf
, 256, "(line: %d, col: %d)", line
, col
);