프로젝트는 C#(입력) 으로 작성된 소스 프로그램을 가져와 Visual Basic(출력) 으로 작성된 대상 프로그램으로 변환하는 컴파일러입니다. 이 프로세스는 각각 세 가지 모듈( Tokenizer , Parser 및 Translator )을 통해 수행됩니다. 각 모듈은 이 보고서에서 별도로 설명됩니다.
Tokenizer/어휘 분석기는 일련의 문자(입력)를 취하고 일련의 토큰을 출력(출력)하는 프로그램입니다.
토크나이저에는 일련의 문자를 그룹화하여 생성할 수 있는 각 토큰에 대한 정의 목록이 있습니다. 각 토큰 정의는 다음으로 구성됩니다.
다음 표는 프로젝트에 사용된 모든 정의를 각 정의에 대해 일치하는 값의 예와 함께 나타냅니다.
| 유형 | 정규식 | 일치하는 값 |
|---|---|---|
| 사용 | 사용하여 | using |
| 수업 | 수업 | class |
| 만약에 | 만약에 | if |
| 또 다른 | 또 다른 | else |
| 을 위한 | ~을 위한 | for |
| 하다 | 하다 | do |
| 하는 동안 | ~하는 동안 | while |
| 스위치 | 스위치 | switch |
| 사례 | 사례 | case |
| 부서지다 | 부서지다 | break |
| 기본 | 기본 | default |
| 반품 | 반품 | return |
| 널 | null | null |
| 진실 | 진실 | true |
| 거짓 | 거짓 | false |
| 거짓 | (공허 | var) | (bool | char | short | int | long | float | double | 십진수 | 문자열 | 문자열) ([] | ?)? | voidboolchar?int[] |
| 유형 | 정규식 | 일치하는 값 |
|---|---|---|
| 숫자 | d*.d+ | d+ | 77.253.14 |
| 끈 | "[^"]*" | "This is string" |
| 식별자 | [a-zA-Z_]w* | fact_privateiD_1 |
| 논평 | (?<=//) .*? (?=(r | n | //)) | // inline comment |
| 여러 줄 주석 | (?<=/*) (?:(?!*/)(?:.|[rn]))* (?=*/) | /*multi linecomment*/ |
| 유형 | 정규식 | 일치하는 값 |
|---|---|---|
| 그리고 | && | & | &&& |
| 또는 | || | | | ||| |
| 아니다 | ! | ! |
| 동일한 | = | = |
| 플러스이퀄 | += | += |
| 빼기같음 | -= | -= |
| DoubleEquals | == | == |
| 같지 않음 | != | != |
| 보다 작음 | < | < |
| 보다 큼 | > | > |
| 작거나 같음 | <= | <= |
| 크거나 같음 | >= | >= |
| 유형 | 정규식 | 일치하는 값 |
|---|---|---|
| OpenRoundBracket | ( | ( |
| 닫기RoundBracket | ) | ) |
| OpenCurlyBracket | { | { |
| 닫기CurlyBracket | } | } |
| OpenSquareBracket | [ | [ |
| CloseSquareBracket | ] | ] |
| 을 더한 | + | + |
| 마이너스 | - | - |
| 더블플러스 | ++ | ++ |
| 더블마이너스 | -- | -- |
| 퍼센트 | % | % |
| 별표 | * | * |
| 백슬래시 | \ | |
| 포워드슬래시 | / | / |
| 이중앞슬래시 | // | // |
| 앞으로슬래시별표 | /* | /* |
| 별표앞으로슬래시 | */ | */ |
| 점 | . | . |
| 콤마 | , | , |
| 콜론 | : | : |
| 세미콜론 | ; | ; |
이러한 모든 토큰 유형은 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 유형의 토큰 입니까? 아니면 Plus 유형의 두 개의 순차 토큰인가요 ? 이 문제는 다음과 같은 다른 중복 토큰에도 적용됩니다. { + , += } & { - , -- } & { - , -= } & { / , // }
해결책:
각 토큰에는 기본값이 0 (가장 높은 우선 순위) 인 우선 순위 속성이 할당되며 두 토큰이 + 및 += 처럼 겹치는 경우 + 길이가 더 짧은 토큰의 우선 순위를 1 로 낮춥니다.
이제 토크나이저는 더 이상 + 와 += 사이를 혼동하지 않고 우선순위가 더 높은 += 선택합니다.
토크나이저가 "String + String = String" 과 같은 일련의 문자에 직면하면 다음과 같은 세 가지 유형 의 토큰을 생성합니다.
"String + String = String"+=하지만 우리는 String 유형의 토큰만 필요합니다!!
해결책:
각 토큰에는 시작 인덱스 및 끝 인덱스 속성이 할당되므로 이전 토큰에는 다음이 포함됩니다.
| 유형 | 값 | 인덱스 시작 | 종료 인덱스 |
|---|---|---|---|
| 끈 | "String + String = String" | 0 | 25 |
| 을 더한 | + | 8 | 9 |
| 동일한 | = | 17 | 18 |
그리고 우리는 다른 토큰 범위 내의 모든 토큰 시작을 무시합니다.
이제 토크나이저는 문자열 유형 의 토큰 하나만 생성하고 내부 토큰은 무시합니다.
파서/구문 분석기는 토큰화기에서 생성된 일련의 토큰을 사용하여 CFG(Context Free Grammar) 생성에 지정된 구조를 형성하도록 그룹화하는 프로그램입니다.
요약:
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 --> == | != | > | >= | < | <=
컴퓨터 과학에서 Backus-Naur 형식(BNF 또는 Backus 일반 형식)은 프로그래밍 언어 또는 기타 형식 언어의 구문을 설명하는 데 사용되는 표기법입니다. John Backus와 Peter Naur가 개발했습니다. BNF는 문맥 자유 문법에 대한 메타 구문 표기법으로 설명할 수 있습니다.
-- Backus–Naur 양식 @ Wikipedia
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자:
참조자: