المشروع عبارة عن مترجم يأخذ البرنامج المصدر المكتوب بلغة C# (الإدخال) ثم يترجمه إلى برنامج هدف مكتوب بلغة Visual Basic (الإخراج) . تتم هذه العملية من خلال المرور عبر ثلاث وحدات ( Tokenizer
و Parser
و Translator
) على التوالي. سيتم شرح كل وحدة بشكل منفصل في هذا التقرير.
Tokenizer / Lexical Analyzer هو برنامج يأخذ سلسلة من الأحرف (الإدخال) ويخرج سلسلة من الرموز المميزة (الإخراج).
يحتوي برنامج الرمز المميز على قائمة تعريفات لكل رمز مميز قد ينتجه عن طريق تجميع سلسلة من الأحرف. يتكون كل تعريف رمزي من:
تمثل الجداول التالية جميع التعريفات المستخدمة في المشروع، مع مثال للقيمة (القيم) المطابقة لكل منها.
يكتب | التعبير العادي | القيمة (القيم) المطابقة |
---|---|---|
استخدام | استخدام | using |
فصل | فصل | class |
لو | لو | if |
آخر | آخر | else |
ل | ل | for |
يفعل | يفعل | do |
بينما | بينما | while |
يُحوّل | يُحوّل | switch |
قضية | قضية | case |
استراحة | استراحة | break |
تقصير | تقصير | default |
يعود | يعود | return |
باطل | باطل | null |
حقيقي | حقيقي | true |
خطأ شنيع | خطأ شنيع | false |
خطأ شنيع | (باطل | فار) | (bool | char | short | int | long | float | double | decimal | string | String) ([] | ؟)؟ | void bool char? int[] |
يكتب | التعبير العادي | القيمة (القيم) المطابقة |
---|---|---|
رقم | d*.d+ | د+ | 77 .25 3.14 |
خيط | "[^"]*" | "This is string" |
المعرف | [أ-zA-Z_]w* | fact _private iD_1 |
تعليق | (?<=//) .*؟ (?=(r | n | //)) | // inline comment |
تعليق متعدد الأسطر | (?<=/*) (?:(؟!*/)(?:.|[rn]))* (?=*/) | /*multi line comment */ |
يكتب | التعبير العادي | القيمة (القيم) المطابقة |
---|---|---|
و | && | & | && & |
أو | || | | | || | |
لا | ! | ! |
متساوي | = | = |
PlusEqual | += | += |
MinusEqual | -= | -= |
يساوي مزدوج | == | == |
ليس متساويا | != | != |
أقل | < | < |
أكبر من | > | > |
أقل من يساوي | <= | <= |
أكبر من يساوي | >= | >= |
يكتب | التعبير العادي | القيمة (القيم) المطابقة |
---|---|---|
OpenRoundBracket | ( | ( |
CloseRoundBracket | ) | ) |
OpenCurlyBracket | { | { |
إغلاقCurlyBracket | } | } |
OpenSquareBracket | [ | [ |
كلوزسكويربراكيت | ] | ] |
زائد | + | + |
ناقص | - | - |
DoublePlus | ++ | ++ |
سلبيات مزدوجة | -- | -- |
نسبة مئوية | % | % |
النجمة | * | * |
شرطة مائلة للخلف | \ |
|
شرطة للأمام | / | / |
DoubleForwardSlashes | // | // |
علامة النجمة المائلة للأمام | /* | /* |
AsteriskForwardSlash | */ | */ |
نقطة | . | . |
فاصلة | , | , |
القولون | : | : |
فاصلة منقوطة | ; | ; |
يتم تجميع كافة أنواع الرموز المميزة هذه في صورة التعداد في ملف TokenType.cs.
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 // ;
}
ويتم إنشاء تعريفاتها وتخزينها في List<TokenDefinition> في ملف Tokenizer.cs.
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 ؟ أو رمزين متسلسلين من النوع Plus ؟ تنطبق هذه المشكلة أيضًا على الرموز المميزة المتداخلة الأخرى مثل: { +
, +=
} & { -
, --
} & { -
, -=
} & { /
, //
}
حل:
سيتم تعيين خاصية أولوية لكل رمز مميز بالقيمة الافتراضية 0 (الأولوية العليا) ، وعندما يتداخل رمزان مميزان مثل +
و +=
نقوم بتقليل أولوية الرمز المميز ذو الطول الأقصر +
ليكون 1 .
الآن، لن يخلط برنامج الرمز المميز بين +
و +=
بعد الآن، وسيأخذ الرمز ذو الأولوية الأعلى +=
.
عندما يواجه برنامج الرمز المميز بعض تسلسل الأحرف مثل "String + String = String"
فإنه سينتج ثلاثة أنواع من الرموز المميزة وهي:
"String + String = String"
+
=
لكننا نحتاج فقط إلى الرمز المميز من النوع String !!
حل:
سيتم تعيين خصائص فهرس البداية وفهرس النهاية لكل رمز مميز، بحيث تحتوي الرموز المميزة السابقة على:
يكتب | قيمة | ابدأ الفهرس | مؤشر النهاية |
---|---|---|---|
خيط | "String + String = String" | 0 | 25 |
زائد | + | 8 | 9 |
متساوي | = | 17 | 18 |
ونتجاهل أي رمز يبدأ ضمن نطاق رمز آخر.
الآن، سينتج أداة الرمز المميز رمزًا مميزًا واحدًا فقط من النوع String ويتجاهل الرموز الداخلية.
Parser / Syntax Analyzer هو برنامج يأخذ سلسلة من الرموز المميزة - التي تم إنشاؤها من Tokenizer - ويجمعها لتكوين هياكل محددة بواسطة إنتاج القواعد النحوية الخالية من السياق (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 أو نموذج باكوس العادي) هو تدوين يستخدم لوصف بناء جملة لغات البرمجة أو اللغات الرسمية الأخرى. تم تطويره بواسطة جون باكوس وبيتر نور. يمكن وصف BNF بأنه تدوين metasyntax للقواعد النحوية الخالية من السياق.
-- نموذج باكوس-نور @ ويكيبيديا
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة:
المشار إليها بواسطة: