/// <summary> /// Set the complete source. /// </summary> /// <param name="source">The source: per line. </param> /// <param name="offset">The offset.</param> public void SetSource(string source, int offset) { Reset(); page_state = TrySetInitialPageState(page_state, source); if (page_state == PageLexerState.PageState_NPL) { lex.SetSource(source, offset); SetOutputToken(); return; } else { bool bDisableWebPageErrors = true; if (bDisableWebPageErrors) { // this is naive way of skipping errors and parse HTML as NPL. page_state = PageLexerState.PageState_NPL; m_bSuppressError = true; lex.SetSource(source, offset); SetOutputToken(); } else { // TODO: this is advanced way: but right now, I can not get the lexer to work // without modifying the auto-generated source code. // Perhaps, the only way is to pre-process all HTML to white space; otherwise lex Scanner source must be modified. // for mixed HTML/npl code, we will split into lines and parse line by line m_lines = Regex.Split(source, "\r?\n"); m_nCurrentLine = 0; NextLine(); } } }
public void Reset() { page_state = PageLexerState.PageState_Uknown; npl_lex_state = 0; m_nCurrentLine = 0; m_lines = null; m_bSuppressError = false; }
private PageLexerState TrySetInitialPageState(PageLexerState page_state, string source) { if (page_state == PageLexerState.PageState_Uknown) { // this is the beginning of file page_state = PageLexerState.PageState_NPL; if (source.Length > 0 && source[0] == '<') { // if file begins with `<`, it is regarded as a .page file with mixed HTML and NPL code. page_state = PageLexerState.PageState_HTML; } } return(page_state); }
private PageLexerState TrySetInitialPageState(PageLexerState page_state) { if (page_state == PageLexerState.PageState_Uknown) { // this is the beginning of file page_state = PageLexerState.PageState_NPL; string sText = lex.yytext; int nPos = lex.buffer.Pos; int nReadPos = lex.buffer.ReadPos; string sChar = lex.buffer.GetString(nReadPos, nReadPos + 1); string sNextChar = lex.buffer.GetString(nPos, nPos + 1); // int nChar = lex.buffer.Peek(); if (sChar == "<") { // if file begins with `<`, it is regarded as a .page file with mixed HTML and NPL code. page_state = PageLexerState.PageState_HTML; } } return(page_state); }
private int ComputeCacheState(int nplLexState, int htmlLexState, PageLexerState pageState) { return(nplLexState | ((int)(htmlLexState) << 4) | ((int)(pageState) << 8)); }
/// <summary> /// Scans the token and provide info about it. /// </summary> /// <param name="tokenInfo">The token info.</param> /// <param name="nStateCache">The state. visual studio cache it per line, so that it can begin parsing from any line /// by passing the cached state of the previous line. /// Initial value(0), Inside comment (1), inside string(2). /// </param> /// <returns></returns> public bool ScanTokenAndProvideInfoAboutIt(TokenInfo tokenInfo, ref int nStateCache) { PageLexerState page_state = GetPageState(nStateCache); int npl_lex_state = GetNPLLexerState(nStateCache); int html_lex_state = GetHTMLLexerState(nStateCache); page_state = TrySetInitialPageState(page_state); int token = (int)Tokens.EOF; int start = lex.buffer.ReadPos; if (lex.buffer.GetString(start, start + 1) == "") { return(false); } int end = 0; if (page_state == PageLexerState.PageState_NPL) { token = lex.GetNext(ref npl_lex_state, out start, out end); } else if (page_state == PageLexerState.PageState_HTML) { // in HTML mode, look for "<[%%%?]n?p?l?=?" string sAllText = lex.buffer.GetString(lex.buffer.ReadPos, MAX_LINE_CHARS); if (sAllText.Length > 0) { Match m = reg_begin_npl_code.Match(sAllText); if (m.Success) { if (m.Index == 0) { end = start + m.Index + m.Length - 1; page_state = PageLexerState.PageState_NPL_IN_HTML; npl_lex_state = 0; token = (int)NPLTokens.LEX_NPL_BEGINCODE; ReadTo(end + 1); } else { int nLastStart = start; int nStartTagIndex = start + m.Index; token = HTMLLexGetNext(ref html_lex_state, out start, out end); if (end >= nStartTagIndex) { start = nLastStart; end = nStartTagIndex; lex.buffer.Pos = end + 1; token = (int)NPLTokens.LEX_COMMENT_LIGHT; } } } else { token = HTMLLexGetNext(ref html_lex_state, out start, out end); } if (start < end && token == (int)Tokens.EOF) { token = (int)NPLTokens.LEX_COMMENT_LIGHT; } } } else if (page_state == PageLexerState.PageState_NPL_IN_HTML) { // in embedded NPL mode, look for "[%%%?]>\r?\n?" // TODO: optimize performance to only search once per line string sAllText = lex.buffer.GetString(lex.buffer.ReadPos, MAX_LINE_CHARS); Match m = reg_end_npl_code.Match(sAllText); if (m.Success) { if (m.Index == 0) { end = start + m.Index + m.Length - 1; ReadTo(end + 1); page_state = PageLexerState.PageState_HTML; npl_lex_state = 0; token = (int)NPLTokens.LEX_NPL_ENDCODE; } else { int nEndTagStart = start + m.Index; token = lex.GetNext(ref npl_lex_state, out start, out end); if (start >= nEndTagStart) { start = nEndTagStart; end = nEndTagStart + m.Length - 1; ReadTo(end + 1); page_state = PageLexerState.PageState_HTML; npl_lex_state = 0; token = (int)NPLTokens.LEX_NPL_ENDCODE; } } } else { token = lex.GetNext(ref npl_lex_state, out start, out end); } } nStateCache = ComputeCacheState(npl_lex_state, html_lex_state, page_state); // !EOL and !EOF if (token != (int)Tokens.EOF) { FillTokenInfo(token, tokenInfo, start, end); return(true); } return(false); }
public override int yylex() { int token = (int)Tokens.EOF; if (page_state == PageLexerState.PageState_NPL) { token = this.lex.yylex(); SetOutputToken(); } else { int start = lex.buffer.ReadPos; int end = 0; if (CheckEndOfText()) { return(this.lex.yylex()); } if (page_state == PageLexerState.PageState_HTML) { // in HTML mode, look for "<[%%%?]n?p?l?=?" string sAllText = lex.buffer.GetString(lex.buffer.ReadPos, MAX_CHARS); if (sAllText.Length > 0) { Match m = reg_begin_npl_code.Match(sAllText); if (m.Success) { end = start + m.Index + m.Length - 1; page_state = PageLexerState.PageState_NPL_IN_HTML; token = ReadTo(end + 1); } else { token = ReadTo(-1); } } if (token == (int)Tokens.EOF) { NextLine(); } return(yylex()); } else if (page_state == PageLexerState.PageState_NPL_IN_HTML) { // in embedded NPL mode, look for "[%%%?]>\r?\n?" bool bRestart = false; string sAllText = lex.buffer.GetString(lex.buffer.ReadPos, MAX_CHARS); Match m = reg_end_npl_code.Match(sAllText); if (m.Success) { if (m.Index == 0) { end = start + m.Index + m.Length - 1; token = ReadTo(end + 1); page_state = PageLexerState.PageState_HTML; bRestart = true; } else { int nEndTagStart = start + m.Index; token = lex.GetNext(ref npl_lex_state, out start, out end); if (start >= nEndTagStart) { start = nEndTagStart; end = nEndTagStart + m.Length - 1; token = ReadTo(end + 1); page_state = PageLexerState.PageState_HTML; bRestart = true; } } } else { token = sAllText.Length == 0 ? (int)Tokens.EOF : lex.GetNext(ref npl_lex_state, out start, out end); if (token == (int)Tokens.EOF) { NextLine(); bRestart = true; } } if (bRestart) { return(yylex()); } SetOutputToken(start, end); } } return(token); }