📄 sql.c
字号:
const int initial = c; int d = fileGetc (); if (d == initial) { if (initial == '<') token->type = TOKEN_BLOCK_LABEL_BEGIN; else token->type = TOKEN_BLOCK_LABEL_END; } else { fileUngetc (d); token->type = TOKEN_UNDEFINED; } break; } case '/': { int d = fileGetc (); if (d != '*') /* is this the start of a comment? */ fileUngetc (d); else { do { skipToCharacter ('*'); c = fileGetc (); if (c == '/') break; else fileUngetc (c); } while (c != '\0'); goto getNextChar; } break; } default: if (! isIdentChar1 (c)) token->type = TOKEN_UNDEFINED; else { parseIdentifier (token->string, c); token->lineNumber = getSourceLineNumber (); token->filePosition = getInputFilePosition (); token->keyword = analyzeToken (token->string); if (isKeyword (token, KEYWORD_rem)) { vStringClear (token->string); skipToCharacter ('\n'); goto getNextChar; } else if (isKeyword (token, KEYWORD_NONE)) token->type = TOKEN_IDENTIFIER; else token->type = TOKEN_KEYWORD; } break; }}/** Scanning functions*/static void findToken (tokenInfo *const token, const tokenType type){ while (! isType (token, type)) readToken (token);}static void skipArgumentList (tokenInfo *const token){ if (isType (token, TOKEN_OPEN_PAREN)) /* arguments? */ { findToken (token, TOKEN_CLOSE_PAREN); readToken (token); }}static void parseSubProgram (tokenInfo *const token){ tokenInfo *const name = newToken (); const sqlKind kind = isKeyword (token, KEYWORD_function) ? SQLTAG_FUNCTION : SQLTAG_PROCEDURE; Assert (isKeyword (token, KEYWORD_function) || isKeyword (token, KEYWORD_procedure)); readToken (name); readToken (token); skipArgumentList (token); if (isKeyword (token, KEYWORD_return)) { do readToken (token); /* read return type */ while (!(isKeyword (token, KEYWORD_is) || isType (token, TOKEN_SEMICOLON))); } if (isKeyword (token, KEYWORD_is)) { if (isType (name, TOKEN_IDENTIFIER)) makeSqlTag (name, kind); readToken (token); parseBlock (token, TRUE); } else if (isType (token, TOKEN_SEMICOLON)) makeSqlTag (name, SQLTAG_PROTOTYPE); deleteToken (name);}static void parseRecord (tokenInfo *const token){ Assert (isType (token, TOKEN_OPEN_PAREN)); do { readToken (token); if (isType (token, TOKEN_IDENTIFIER)) makeSqlTag (token, SQLTAG_FIELD); while (!(isType (token, TOKEN_COMMA) || isType (token, TOKEN_CLOSE_PAREN))) readToken (token); } while (! isType (token, TOKEN_CLOSE_PAREN));}static void parseType (tokenInfo *const token){ tokenInfo *const name = newToken (); readToken (name); if (isType (name, TOKEN_IDENTIFIER)) { readToken (token); if (isKeyword (token, KEYWORD_is)) { readToken (token); switch (token->keyword) { case KEYWORD_record: makeSqlTag (name, SQLTAG_RECORD); parseRecord (token); break; case KEYWORD_table: makeSqlTag (name, SQLTAG_TABLE); break; case KEYWORD_ref: readToken (token); if (isKeyword (token, KEYWORD_cursor)) makeSqlTag (name, SQLTAG_CURSOR); break; default: break; } } } deleteToken (name);}static void parseSimple (tokenInfo *const token, const sqlKind kind){ readToken (token); if (isType (token, TOKEN_IDENTIFIER)) makeSqlTag (token, kind);}static void parseDeclare (tokenInfo *const token, const boolean local){ if (isKeyword (token, KEYWORD_declare)) readToken (token); while (! isKeyword (token, KEYWORD_begin) && ! isKeyword (token, KEYWORD_end)) { switch (token->keyword) { case KEYWORD_cursor: parseSimple (token, SQLTAG_CURSOR); break; case KEYWORD_function: parseSubProgram (token); break; case KEYWORD_procedure: parseSubProgram (token); break; case KEYWORD_subtype: parseSimple (token, SQLTAG_SUBTYPE); break; case KEYWORD_trigger: parseSimple (token, SQLTAG_TRIGGER); break; case KEYWORD_type: parseType (token); break; default: if (isType (token, TOKEN_IDENTIFIER)) { if (local) makeSqlTag (token, SQLTAG_LOCAL_VARIABLE); else makeSqlTag (token, SQLTAG_VARIABLE); } break; } findToken (token, TOKEN_SEMICOLON); readToken (token); }}static void parseLabel (tokenInfo *const token){ Assert (isType (token, TOKEN_BLOCK_LABEL_BEGIN)); readToken (token); if (isType (token, TOKEN_IDENTIFIER)) { makeSqlTag (token, SQLTAG_BLOCK_LABEL); readToken (token); /* read end of label */ }}static void parseStatements (tokenInfo *const token){ do { if (isType (token, TOKEN_BLOCK_LABEL_BEGIN)) parseLabel (token); else { switch (token->keyword) { case KEYWORD_if: case KEYWORD_loop: readToken (token); parseStatements (token); break; case KEYWORD_declare: case KEYWORD_begin: parseBlock (token, TRUE); break; default: readToken (token); break; } findToken (token, TOKEN_SEMICOLON); } readToken (token); } while (! isKeyword (token, KEYWORD_end));}static void parseBlock (tokenInfo *const token, const boolean local){ if (isType (token, TOKEN_BLOCK_LABEL_BEGIN)) { parseLabel (token); readToken (token); } if (! isKeyword (token, KEYWORD_begin)) parseDeclare (token, local); if (isKeyword (token, KEYWORD_begin)) { readToken (token); while (! isKeyword (token, KEYWORD_end)) parseStatements (token); findToken (token, TOKEN_SEMICOLON); }}static void parsePackage (tokenInfo *const token){ tokenInfo *const name = newToken (); readToken (name); if (isKeyword (name, KEYWORD_body)) readToken (name); readToken (token); if (isKeyword (token, KEYWORD_is)) { if (isType (name, TOKEN_IDENTIFIER)) makeSqlTag (name, SQLTAG_PACKAGE); readToken (token); parseBlock (token, FALSE); } findToken (token, TOKEN_SEMICOLON); deleteToken (name);}static void parseTable (tokenInfo *const token){ tokenInfo *const name = newToken (); readToken (name); readToken (token); if (isType (token, TOKEN_OPEN_PAREN)) { if (isType (name, TOKEN_IDENTIFIER)) { makeSqlTag (name, SQLTAG_TABLE); parseRecord (token); } } findToken (token, TOKEN_SEMICOLON); deleteToken (name);}static void parseSqlFile (tokenInfo *const token){ do { readToken (token); if (isType (token, TOKEN_BLOCK_LABEL_BEGIN)) parseLabel (token); else switch (token->keyword) { case KEYWORD_begin: parseBlock (token, FALSE); break; case KEYWORD_cursor: parseSimple (token, SQLTAG_CURSOR); break; case KEYWORD_declare: parseBlock (token, FALSE); break; case KEYWORD_function: parseSubProgram (token); break; case KEYWORD_package: parsePackage (token); break; case KEYWORD_procedure: parseSubProgram (token); break; case KEYWORD_subtype: parseSimple (token, SQLTAG_SUBTYPE); break; case KEYWORD_table: parseTable (token); break; case KEYWORD_trigger: parseSimple (token, SQLTAG_TRIGGER); break; case KEYWORD_type: parseType (token); break; default: break; } } while (! isKeyword (token, KEYWORD_end));}static void initialize (const langType language){ Assert (sizeof (SqlKinds) / sizeof (SqlKinds [0]) == SQLTAG_COUNT); Lang_sql = language; buildSqlKeywordHash ();}static void findSqlTags (void){ tokenInfo *const token = newToken (); exception_t exception = (exception_t) (setjmp (Exception)); while (exception == ExceptionNone) parseSqlFile (token); deleteToken (token);}extern parserDefinition* SqlParser (void){ static const char *const extensions [] = { "sql", NULL }; parserDefinition* def = parserNew ("SQL"); def->kinds = SqlKinds; def->kindCount = KIND_COUNT (SqlKinds); def->extensions = extensions; def->parser = findSqlTags; def->initialize = initialize; return def;}/* vi:set tabstop=4 shiftwidth=4: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -