このプロジェクトは、C# で記述されたソース プログラム (入力)を取得し、それをVisual Basic で記述されたターゲット プログラム (出力)に変換するコンパイラーです。このプロセスは、3 つのモジュール ( Tokenizer
、 Parser
、およびTranslator
) をそれぞれ通過することによって実行されます。このレポートでは、各モジュールについて個別に説明します。
Tokenizer / Lexical Analyzer は、一連の文字 (入力) を受け取り、一連のトークン (出力) を出力するプログラムです。
トークナイザーには、一連の文字をグループ化することによって生成される可能性のある各トークンの定義のリストがあります。各トークン定義は次のもので構成されます。
次の表は、プロジェクトで使用されるすべての定義と、それぞれに一致する値の例を示しています。
タイプ | 正規表現 | 一致した値 |
---|---|---|
使用する | を使用して | using |
クラス | クラス | class |
もし | もし | if |
それ以外 | それ以外 | else |
のために | のために | for |
する | する | do |
その間 | その間 | while |
スイッチ | スイッチ | switch |
場合 | 場合 | case |
壊す | 壊す | break |
デフォルト | デフォルト | default |
戻る | 戻る | return |
ヌル | ヌル | null |
真実 | 真実 | true |
間違い | 間違い | false |
間違い | (void | var) | (bool | char | short | int | long | float | double | 10 進数 | string | String) ([] | ?)? | void bool char? int[] |
タイプ | 正規表現 | 一致した値 |
---|---|---|
番号 | d*.d+ | d+ | 77 .25 3.14 |
弦 | 「[^"]*」 | "This is string" |
識別子 | [a-zA-Z_]w* | fact _private iD_1 |
コメント | (?<=//) .*? (?=(r | n | //)) | // inline comment |
複数行コメント | (?<=/*) (?:(?!*/)(?:.|[rn]))* (?=*/) | /*multi line comment */ |
タイプ | 正規表現 | 一致した値 |
---|---|---|
そして | && | & | && & |
または | || | | | || | |
ない | ! | ! |
等しい | = | = |
プラスイコール | += | += |
マイナスイコール | -= | -= |
ダブルイコール | == | == |
等しくない | != | != |
未満 | < | < |
より大きい | > | > |
以下 | <= | <= |
より大きいか等しい | >= | >= |
タイプ | 正規表現 | 一致した値 |
---|---|---|
オープンラウンドブラケット | ( | ( |
閉じるラウンドブラケット | ) | ) |
オープンカーリーブラケット | { | { |
閉じる中括弧 | } | } |
オープンスクエアブラケット | [ | [ |
四角括弧を閉じる | ] | ] |
プラス | + | + |
マイナス | - | - |
ダブルプラス | ++ | ++ |
ダブルマイナス | -- | -- |
パーセント | % | % |
アスタリスク | * | * |
バックスラッシュ | \ |
|
フォワードスラッシュ | / | / |
ダブルフォワードスラッシュ | // | // |
フォワードスラッシュアスタリスク | /* | /* |
アスタリスク前進スラッシュ | */ | */ |
ドット | 。 | . |
コンマ | 、 | , |
結腸 | : | : |
セミコロン | ; | ; |
これらすべてのトークン タイプは、TokenType.cs ファイル内でenumとしてグループ化されます。
public enum TokenType
{
// Keywords
Using , // using
Class , // class
If , // if
Else , // else
For , // for
Do , // do
While , // while
Switch , // switch
Case , // case
Break , // break
Default , // default
Return , // return
Null , // null
True , // true
False , // false
DataType , // void | bool | char? | int[]
// Values
Number , // 77 | .25 | 3.14
String , // "I am 'Moaz'"
Comment , // Any Character After (//) and Before (r | n | //)
Identifier , // fact | _private | iD_1
MultilineComment , // Any Character After (/*) and Before (*/)
// Operators
And , // && | &
Or , // || | |
Not , // !
Equal , // =
PlusEqual , // +=
MinusEqual , // -=
DoubleEquals , // ==
NotEqual , // !=
LessThan , // <
GreaterThan , // >
LessThanOrEqual , // <=
GreaterThanOrEqual , // >=
// Symbols
OpenRoundBracket , // (
CloseRoundBracket , // )
OpenCurlyBracket , // {
CloseCurlyBracket , // }
OpenSquareBracket , // [
CloseSquareBracket , // ]
Plus , // +
Minus , // -
DoublePluses , // ++
DoubleMinuses , // --
Percent , // %
Asterisk , // *
BackSlash , //
ForwardSlash , // /
DoubleForwardSlashes , // //
ForwardSlashAsterisk , // /*
AsteriskForwardSlash , // */
Dot , // .
Comma , // ,
Colon , // :
Semicolon // ;
}
その定義は、Tokenizer.cs ファイルのList<TokenDefinition>に作成されて保存されます。
private readonly List < TokenDefinition > _tokenDefinitions = new List < TokenDefinition >
{
// Keywords
new TokenDefinition ( TokenType . Using , @"using" ) ,
new TokenDefinition ( TokenType . Class , @"class" ) ,
new TokenDefinition ( TokenType . If , @"if" ) ,
new TokenDefinition ( TokenType . Else , @"else" ) ,
new TokenDefinition ( TokenType . For , @"for" ) ,
new TokenDefinition ( TokenType . Do , @"do" , 1 ) ,
new TokenDefinition ( TokenType . While , @"while" ) ,
new TokenDefinition ( TokenType . Switch , @"switch" ) ,
new TokenDefinition ( TokenType . Case , @"case" ) ,
new TokenDefinition ( TokenType . Default , @"default" ) ,
new TokenDefinition ( TokenType . Break , @"break" ) ,
new TokenDefinition ( TokenType . Return , @"return" ) ,
new TokenDefinition ( TokenType . Null , @"null" ) ,
new TokenDefinition ( TokenType . True , @"true" ) ,
new TokenDefinition ( TokenType . False , @"false" ) ,
new TokenDefinition ( TokenType . DataType , @"(void|var)|(bool|char|short|int|long|float|double|decimal|String|string)([]|?)?" ) ,
// Values
new TokenDefinition ( TokenType . Number , @"d*.d+|d+" ) ,
new TokenDefinition ( TokenType . String , @"""[^""]*""" ) ,
new TokenDefinition ( TokenType . Identifier , @"[a-zA-Z_]w*" , 1 ) ,
new TokenDefinition ( TokenType . Comment , @"(?<=//).*?(?=(r|n|//))" ) ,
new TokenDefinition ( TokenType . MultilineComment , @"(?<=/*)(?:(?!*/)(?:.|[rn]))*(?=*/)" ) ,
// Operators
new TokenDefinition ( TokenType . And , @"&&|&" ) ,
new TokenDefinition ( TokenType . Or , @"||||" ) ,
new TokenDefinition ( TokenType . Not , @"!" , 1 ) ,
new TokenDefinition ( TokenType . Equal , @"=" , 1 ) ,
new TokenDefinition ( TokenType . PlusEqual , @"+=" ) ,
new TokenDefinition ( TokenType . MinusEqual , @"-=" ) ,
new TokenDefinition ( TokenType . DoubleEquals , @"==" ) ,
new TokenDefinition ( TokenType . NotEqual , @"!=" ) ,
new TokenDefinition ( TokenType . LessThan , @"<" , 1 ) ,
new TokenDefinition ( TokenType . GreaterThan , @">" , 1 ) ,
new TokenDefinition ( TokenType . LessThanOrEqual , @"<=" ) ,
new TokenDefinition ( TokenType . GreaterThanOrEqual , @">=" ) ,
// Symbols
new TokenDefinition ( TokenType . OpenRoundBracket , @"(" ) ,
new TokenDefinition ( TokenType . CloseRoundBracket , @")" ) ,
new TokenDefinition ( TokenType . OpenCurlyBracket , @"{" ) ,
new TokenDefinition ( TokenType . CloseCurlyBracket , @"}" ) ,
new TokenDefinition ( TokenType . OpenSquareBracket , @"[" ) ,
new TokenDefinition ( TokenType . CloseSquareBracket , @"]" ) ,
new TokenDefinition ( TokenType . Plus , @"+" , 1 ) ,
new TokenDefinition ( TokenType . Minus , @"-" , 1 ) ,
new TokenDefinition ( TokenType . DoublePluses , @"++" ) ,
new TokenDefinition ( TokenType . DoubleMinuses , @"--" ) ,
new TokenDefinition ( TokenType . Percent , @"%" ) ,
new TokenDefinition ( TokenType . Asterisk , @"*" , 1 ) ,
new TokenDefinition ( TokenType . BackSlash , @"\" ) ,
new TokenDefinition ( TokenType . ForwardSlash , @"/" , 1 ) ,
new TokenDefinition ( TokenType . DoubleForwardSlashes , @"//" ) ,
new TokenDefinition ( TokenType . ForwardSlashAsterisk , @"/*" ) ,
new TokenDefinition ( TokenType . AsteriskForwardSlash , @"*/" ) ,
new TokenDefinition ( TokenType . Dot , @"." ) ,
new TokenDefinition ( TokenType . Comma , @"," ) ,
new TokenDefinition ( TokenType . Colon , @":" ) ,
new TokenDefinition ( TokenType . Semicolon , @";" ) ,
} ;
.. .
トークナイザーが++
ような文字のシーケンスに直面すると混乱しますが、それはDoublePluses型の1 つのトークンですか?それともPlusタイプの2 つの連続したトークンですか?この問題は、{ +
, +=
} & { -
, --
} & { -
, -=
} & { /
, //
} のような他の重複するトークンにも当てはまります。
解決:
各トークンには、デフォルト値0 (最高優先度)のPriorityプロパティが割り当てられます。 +
と+=
のように 2 つのトークンが重なる場合、長さの短い+
の優先度が1に下がります。
これで、トークナイザーは+
と+=
の間で混乱することがなくなり、優先度の高い+=
採用するようになります。
トークナイザーが"String + String = String"
のような文字シーケンスに直面すると、次の3 種類のトークンが生成されます。
"String + String = String"
+
=
ただし、必要なのは文字列型のトークンだけです。
解決:
各トークンには開始インデックスと終了インデックスのプロパティが割り当てられるため、以前のトークンは次のようになります。
タイプ | 価値 | 開始インデックス | 終了インデックス |
---|---|---|---|
弦 | "String + String = String" | 0 | 25 |
プラス | + | 8 | 9 |
等しい | = | 17 | 18 |
そして、別のトークンの範囲内で始まるトークンは無視されます。
現在、トークナイザーはString型のトークンを 1 つだけ生成し、内部のトークンは無視します。
パーサー / 構文アナライザーは、トークナイザーから生成された一連のトークンを取得し、それらをグループ化して、使用されているコンテキスト フリー グラマー (CFG) の生成物によって指定された構造を形成するプログラムです。
まとめ:
CAPITAL_CASE
: 非終端文字small_case
: ターミナル|
: 代替 (または)ε
: 空 PROGRAM --> IMPORTS CLASSES
IMPORTS --> IMPORT_STATEMENT IMPORTS | ε
IMPORT_STATEMENT --> using IDS;
CLASSES --> CLASS_STATEMENT CLASSES | ε
CLASS_STATEMENT --> class id { SUPER_STATEMENTS }
SUPER_STATEMENTS --> SUPER_STATEMENT SUPER_STATEMENTS | ε
SUPER_STATEMENT --> COMMENT_STATEMENT | FUNCTION_STATEMENT | INLINE_STATEMENT ;
COMMENT_STATEMENT --> // comment | /* multiline_comment */
FUNCTION_STATEMENT --> data_type id (DECLARES) { STATEMENTS }
INLINE_STATEMENT --> DECSIGN_STATEMENT | DECLARE_STATEMENT | INC_DEC_STATEMENT | ASSIGN_STATEMENT | CALL_STATEMENT
DECSIGN_STATEMENT --> data_type id = EXPRESSION
DECLARE_STATEMENT --> data_type id
INC_DEC_STATEMENT --> id INC_DEC_OPERATOR
ASSIGN_STATEMENT --> id ASSIGN_OPERATOR EXPRESSION
CALL_STATEMENT --> IDS(EXPRESSIONS)
STATEMENTS --> STATEMENT STATEMENTS | ε
STATEMENT --> SUPER_STATEMENT | STRUCT_STATEMENT
STRUCT_STATEMENT --> IF_STATEMENT | WHILE_STATEMENT | DO_WHILE_STATEMENT | FOR_STATEMENT | BLOCK_STATEMENT | RETURN_STATEMENT | SWITCH_STATEMENT
IF_STATEMENT --> if (CONDITION) STATEMENT ELSE_STATEMENT
ELSE_STATEMENT --> else STATEMENT | ε
WHILE_STATEMENT --> while (CONDITION) STATEMENT
DO_WHILE_STATEMENT --> do STATEMENT while (CONDITION);
FOR_STATEMENT --> for (INLINE_STATEMENT; CONDITION; INLINE_STATEMENT) STATEMENT
BLOCK_STATEMENT --> { STATEMENTS }
RETURN_STATEMENT --> return RETURN_STATEMENT_REST;
RETURN_STATEMENT_REST --> EXPRESSION | ε
SWITCH_STATEMENT --> switch (EXPRESSION) { CASES }
CASES --> CASE CASES | ε
CASE --> CASE_STATEMENT | DEFAULT_STATEMENT
CASE_STATEMENT --> case VALUE: STATEMENT break;
DEFAULT_STATEMENT --> default: STATEMENT break;
CONDITION --> EXPRESSION REL_OPERATOR EXPRESSION | true | false
EXPRESSION --> VALUE | id | ( EXPRESSION )
VALUE --> string | number | true | false | null
IDS --> id MORE_IDS
MORE_IDS --> .IDS | ε
DECLARES --> DECLARE_STATEMENT MORE_DECLARES | ε
MORE_DECLARES --> , DECLARES | ε
EXPRESSIONS --> EXPRESSION MORE_EXPRESSIONS | ε
MORE_EXPRESSIONS --> , EXPRESSIONS | ε
INC_DEC_OPERATOR --> ++ | --
ASSIGN_OPERATOR --> = | += | -=
REL_OPERATOR --> == | != | > | >= | < | <=
コンピューターサイエンスにおいて、バッカス・ナウア形式 (BNF またはバッカス標準形式) は、プログラミング言語またはその他の形式言語の構文を記述するために使用される表記法です。 John Backus と Peter Naur によって開発されました。 BNF は、文脈自由文法のメタ構文表記として説明できます。
--バッカス・ナウア形式 @ Wikipedia
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元:
参照元: