#include "parser.h"
-CParser Parser;
+
int main(int argc, char *argv[])
{
- FILE *fp;
+ CParser Parser;
+ FILE *fp;
+ TSourceInfo SrcInf;
+ // さしあたって適当にテスト
if ( (fp = fopen("system.i", "r")) == NULL )
{
return 1;
}
- Parser.Analyze(fp);
-
-#if 0
- CParamBlock param;
- CParamBlock *pParam2;
-
- param.AddString("aaaa");
- param.AddString("bbbb");
- pParam2 = param.AddParamBlock();
- pParam2->AddString("ccc");
- pParam2->AddString("ddd");
- param.AddString("eeeeeeeeeeeeeeee");
- CDebug::PrintParam(¶m, 0);
-#endif
+ SrcInf.strFileName = "system.i";
+ SrcInf.iLineNum = 1;
+ SrcInf.iColumnNum = 1;
+ Parser.Analyze(fp, &SrcInf);
return 0;
}
+/**
+ * Hyper Operating System V4 Advance configurator
+ *
+ * @file parser.cpp
+ * @brief %jp{字句解析のクラス}%en{lexical analyzer class}
+ *
+ * Copyright (C) 1998-2006 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
#include <stdio.h>
-// 1文字読む
-int CParser::GetChar(void)
-{
- int c;
-
- while ( (c = fgetc(m_fpInput)) == '\r' )
- ;
-
- if ( c == '\n' )
- {
- m_SrcInf.m_iLineNum++;
- m_SrcInf.m_iColumnNum = 0;
- }
- else
- {
- m_SrcInf.m_iColumnNum++;
- }
-
- if ( c == '\n' ) // 改行文字なら
- {
- m_blNewLine = true; // 行頭フラグON
- }
- else if ( isspace(c) ) // 空白文字なら
- {
- // 何もしない
- }
- else if ( c == '#' ) // 行頭に#がきたらプリプロセッサ行判定
- {
- if ( m_blNewLine )
- {
- m_blPreProc = true;
- m_blNewLine = false;
- }
- }
- else // 通常の文字なら
- {
- m_blNewLine = false; // 行頭フラグクリア
- }
-
- return c;
-}
-
-
-// 1文字戻す
-void CParser::UngetChar(int c)
-{
- ungetc(c, m_fpInput);
- if ( c == '\n' )
- {
- m_SrcInf.m_iLineNum--;
- }
- else
- {
- m_SrcInf.m_iColumnNum--;
- }
-}
-
-
-
// API部解析状態
#define PARSER_STATE_API_START 2000 // API探索中
#define PARSER_STATE_API_END 2001 // APIの終結探索
#define PARSER_STATE_API_ERR_1 3001 // エラー発生 API末尾の ";" まで読み飛ばし中
// 字句解析
-bool CParser::Analyze(FILE *fp)
+bool CParser::Analyze(FILE *fp, const TSourceInfo *pSrcInf)
{
int c;
- m_fpInput = fp;
-
+ // %jp{初期設定}
+ m_fpInput = fp;
+ m_SrcInf = *pSrcInf;
m_blPreProc = false;
m_blNewLine = true;
m_iApiState = PARSER_STATE_API_START;
+
while ( (c = GetChar()) != EOF )
{
if ( m_blPreProc ) // プリプロセッサ行の処理
}
+
#define PARSER_STATE_PARAM_START 40000
#define PARSER_STATE_PARAM_NORMAL 40001
#define PARSER_STATE_PARAM_STR 40002
}
+// プリプロセッサ行の処理
bool CParser::PreProc(void)
{
printf("PRI : %s\n", m_strPre.c_str());
return true;
}
+
bool CParser::ApiProc(void)
{
printf("API : %s\n", m_strApiName.c_str());
}
+// 1文字読む
+int CParser::GetChar(void)
+{
+ int c;
+
+ while ( (c = fgetc(m_fpInput)) == '\r' )
+ ;
+
+ if ( c == '\n' )
+ {
+ m_SrcInf.iLineNum++;
+ m_SrcInf.iColumnNum = 0;
+ }
+ else
+ {
+ m_SrcInf.iColumnNum++;
+ }
+
+ if ( c == '\n' ) // 改行文字なら
+ {
+ m_blNewLine = true; // 行頭フラグON
+ }
+ else if ( isspace(c) ) // 空白文字なら
+ {
+ // 何もしない
+ }
+ else if ( c == '#' ) // 行頭に#がきたらプリプロセッサ行判定
+ {
+ if ( m_blNewLine )
+ {
+ m_blPreProc = true;
+ m_blNewLine = false;
+ }
+ }
+ else // 通常の文字なら
+ {
+ m_blNewLine = false; // 行頭フラグクリア
+ }
+
+ return c;
+}
+
+
+// 1文字戻す
+void CParser::UngetChar(int c)
+{
+ ungetc(c, m_fpInput);
+ if ( c == '\n' )
+ {
+ m_SrcInf.iLineNum--;
+ }
+ else
+ {
+ m_SrcInf.iColumnNum--;
+ }
+}
+
+
+
void CParser::ParseError(int iType, int iCode)
{
printf("err\n");
+/**
+ * Hyper Operating System V4 Advance configurator
+ *
+ * @file parser.h
+ * @brief %jp{字句解析のクラス}%en{lexical analyzer class}
+ *
+ * Copyright (C) 1998-2006 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
#ifndef __parser_h__
#define __parser_h__
+
#include <stdio.h>
#include "param.h"
#include "srcinf.h"
-// レキシカルアナライザなクラス
+
+// %jp{字句解析のクラス}%en{lexical analyzer class}
class CParser
{
public:
- bool Analyze(FILE *fp);
+ bool Analyze(FILE *fp, const TSourceInfo *pSrcInf);
protected:
- int GetChar(void);
- void UngetChar(int c);
+ int GetChar(void); // %jp{1文字読み込む}
+ void UngetChar(int c); // %jp{1文字戻す}
- bool AnalyzePreProc(void);
- bool AnalyzeParam(CParamBlock *pBlock, int cEndChar);
+ bool AnalyzePreProc(void); // %jp{プリプロセッサ文の解析}
+ bool AnalyzeParam(CParamBlock *pBlock, int cEndChar); // %jp{パラメータ部の分解}
bool PreProc(void);
bool ApiProc(void);
void ParseError(int iType, int iCode);
- FILE *m_fpInput; // 入力ファイル
+ FILE* m_fpInput; // %jp{入力ファイル}
+ TSourceInfo m_SrcInf; // %jp{ソースコード情報}
- TSourceInfo m_SrcInf;
+ bool m_blPreProc; // %jp{プリプロセッサ文処理フラグ}
+ bool m_blNewLine; // %jp{行頭フラグ}
+ int m_iPreState; // %jp{プリプロセッサ文処理状態}
+ int m_iApiState; // %jp{API部処理状態}
- bool m_blPreProc;
- bool m_blNewLine;
- int m_iPreState;
- int m_iApiState;
+ string m_strPre; // %jp{プリプロセッサ行}
+ string m_strApiName; // %jp{API名}
+ CParamBlock m_ApiParam; // %jp{APIのパラメータ}
+};
- string m_strPre; // プリプロセッサ行
- string m_strParam; // API名
- string m_strApiName; // API名
- CParamBlock m_ApiParam; // APIのパラメータ
-};
+#endif // __parser_h__
+
-#endif // __parser_h__
\ No newline at end of file
+// end of file
// ソースファイルの情報
struct TSourceInfo
{
- string m_strFileName; // 入力ファイル名
- int m_iLineNum; // 処理中の行番号
- int m_iColumnNum; // 処理中の桁番号
+ string strFileName; // 入力ファイル名
+ int iLineNum; // 処理中の行番号
+ int iColumnNum; // 処理中の桁番号
};
-#include <stdlib.h>
-
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
#include <string>
using namespace std;
-// パラメータ文字列を正規化する
-void RegularizeParam(string &strSrc)
+// パラメータ文字列を正規化する(余分空白文字の削除)
+string RegularizeParam(const char *pszString)
{
- string strDst;
+ string str;
+ bool blSpace = false;
+ int iLen;
+ int i;
+
+ // 先頭の空白を読み飛ばし
+ while ( isspace(*pszString) )
+ {
+ pszString++;
+ }
+ // 後半の空白も除外
+ iLen = strlen(pszString);
+ while ( iLen > 0 && isspace(pszString[iLen - 1]) )
+ {
+ iLen--;
+ }
+
+ // 正規化
+ for ( i = 0; i < iLen; i++ )
+ {
+ if ( blSpace ) // 空白の続きなら
+ {
+ if ( !isspace(pszString[i]) ) // 空白が続く限り読み飛ばし
+ {
+ str += pszString[i];
+ blSpace = false;
+ }
+ }
+ else
+ {
+ if ( isspace(pszString[i]) )
+ {
+ str += ' '; // 空白文字はシングルスペースに置換
+ blSpace = true;
+ }
+ else
+ {
+ str += pszString[i];
+ }
+ }
+ }
+
+ return str;
}
+
+// 文字列定数の展開
+string AnalyzeConstantString(const char *pszString)
+{
+ bool blEsc = false;
+ string str;
+ int c;
+
+ // 文字列開始まで読み飛ばし
+ while ( (c = *pszString++) != '\0' )
+ {
+ if ( c == '\"' )
+ {
+ break;
+ }
+ }
+ if ( c == '\0' )
+ {
+ return ""; // エラー
+ }
+
+ // 文字列展開
+ while ( (c = *pszString++) != '\0' )
+ {
+ if ( blEsc )
+ {
+ if ( c == 'a' )
+ {
+ str += '\a';
+ }
+ else if ( c == 'b' )
+ {
+ str += '\b';
+ }
+ else if ( c == 'f' )
+ {
+ str += '\f';
+ }
+ else if ( c == 'n' )
+ {
+ str += '\n';
+ }
+ else if ( c == 'r' )
+ {
+ str += '\r';
+ }
+ else if ( c == 't' )
+ {
+ str += '\t';
+ }
+ else if ( c == 'v' )
+ {
+ str += '\v';
+ }
+ else if ( c == 'x' )
+ {
+ char *next;
+ c = (char)strtol(pszString, &next, 16);
+ pszString = (const char*)next;
+ str += c;
+ }
+ else if ( c == '0' )
+ {
+ char *next;
+ c = (char)strtol(pszString, &next, 8);
+ pszString = (const char*)next;
+ str += c;
+ }
+ else
+ {
+ str += c;
+ }
+ blEsc = false;
+ }
+ else
+ {
+ if ( c == '\"' )
+ {
+ break;
+ }
+ else if ( c == '\\' )
+ {
+ blEsc = true;
+ }
+ else
+ {
+ str += c;
+ }
+ }
+ }
+ if ( c == '\0' )
+ {
+ return ""; // エラー
+ }
+
+ return str;
+}
+
+
// 数値として有効かチェック
bool CheckNumber(const char *pszStr)
{
return true;
}
-
// 識別子として有効かチェック
bool CheckIdentifier(const char *pszStr)
{