언어 20

재귀하강

좌순환 문제LL에서 top down parser는 사용될 수 없다. 따라서 해당 문법이 있으면 제거 후 사용해야 한다. // ex) A → A + B 의 경우 A + A + B ...로 좌순환 재귀 하강 파서 recursive descent parser 우선 EBNF에 대해 간단히 설명 → if [ else ] → ident {, ident} 여기서 []는 선택, {}는 반복의 의미를 갖는다. → {(+ | -) } → {(* | /) } → id | int_constant | () 이와 같은 산술 표현식에 대한 EBNF 문법은 어떤 결합성 규칙도 강요하지 않는다. 하지만 우리는 코드 생성 프로세스가 언어의 결합성 규칙을 준수하는 코드를 생성하는지 확인해야 한다. 이 때, 재귀 하강 구문 분석을 사용하여..

어휘 및 구문 분석

구문 분석에서 특히 자주 나올 terminal과 non terminal의 의미에 대해 알아보자 PL(프로그래밍 언어)에서 "terminal"과 "non-terminal"은 문법적인 요소를 나타내는 용어입니다. 이 용어들은 주로 형식 문법(또는 문법 규칙)에 관련이 있으며, 프로그래밍 언어의 구조를 정의하고 해석하는 데 사용됩니다. Terminal: 터미널은 언어에서 실제로 사용되는 단어나 기호를 나타냅니다. 이러한 터미널은 파싱 과정에서 더 이상 분해되거나 확장되지 않습니다. 예를 들어, 프로그래밍 언어의 터미널 요소로는 예약어(예: if, while, for), 식별자(변수나 함수의 이름), 숫자, 연산자(예: +, -, *, /) 등이 있습니다. 터미널은 문법적으로 더 이상 분해되지 않으므로 이러한 ..

구문의 의미론에 대한 과정

BNF와 문맥 context free grammar는 동등한 메타언어이다. ( 다른 언어를 기술하거나 설명하는 언어 ) 이는 프로그래밍 언어의 구문을 설명하는 데 적합하다. attribute grammar는 언어의 구문과 의미를 모두 설명할 수 있는 기술 형식 의미론적 설명의 세 가지 주요 방법 언어 Denotational Semantics (의미 표현론): Denotational semantics는 프로그램의 의미를 수학적인 객체나 구조로 표현하는 방법을 제공합니다. 이 접근 방식은 수학적인 함수나 수식을 사용하여 프로그램의 동작을 형식적으로 설명합니다. Denotational semantics에서, 각 프로그램 구성 요소는 어떻게 동작하며 어떤 결과를 생성하는지를 나타내는 함수나 의미론적 객체에 매핑..

구문 표현하기

Syntax: 표현식, 명령문, 프로그램 단위의 형식이나 구조 ex) while (bool_expr){} 여기서 while문, for문 등등 구문 자체를 의미 • Semantics: 표현식, 명령문, 프로그램 단위의 의미 bool 표현식(bool_expr)의 현재 값이 true인 경우 포함된 문이 실행됩니다. bool 표현식(bool_expr)이 false인 경우 제어는 while 구문 다음의 명령문으로 전달됩니다 구문과 의미론은 언어의 정의를 제공한다. 여기서 문장 sentence : 일부 알파벳에 대한 문자열의 집합. (명령문이라고도 한다.) 언어 language : 문장의 집합 어휘소 lexeme : 언어의 가장 낮은 수준의 구문 단위 ex) *, sum 토큰 token : lexeme의 범주에 있..

프로그래밍 언어를 사용하는 이유

우리가 프로그래밍 언어를 공부하는 이유는 말로 표현하기 복잡하고 추상적인 아이디어를 표현하는 능력이 향상된다. 언어에 따라 제어 구조, 데이터 구조 및 추상화의 종류에 따라 제한이 있다. 이에 따라서 우리가 구성할 수 있는 알고리즘도 제한되는데 다양한 프로그래밍 언어를 공부함으로서 이런 제한을 극복할 수 있다. 적절한 언어를 선택하는데 도움을 준다. 설계가 언어에 통합된 기능을 사용하는 것이 더 좋다. 복잡한 코드보다 더 우아하고, 덜 번거롭고, 더 안전하기 때문이다. 새로운 언어를 배우는 능력이 향상된다. 모국어의 문법을 더 잘 알수록 제2외국어를 배우는 것이 더 쉬워짐과 같다. 이 점에서 현직 프로그래머는 프로그래밍 언어의 어휘와 기본 개념을 알아야 프로그래밍 언어 설명 및 평가는 물론 언어 및 컴파..

객체지향의 3대 속성 [은닉성, 상속성, 다형성]

상속 데이터를 효율적으로 관리하기 위해 사용한다. class 사람{ } 이렇게 사람에 대한 class를 만들어서 그 기능을 넣는다고 한다면 class 학생 : 사람 { } 으로 사람에 넣었던 필드와 함수들을 학생class 안에서도 사용할 수 있다. 코드의 흐름은 부모의 class에 있는 필드와 메소드를 읽어들인 후 자식class를 실행한다. 따라서 부모와 자식의 class에 각각 생성자가 있다면 부모의 생성자 먼저 호출된 후 자식의 생성자가 호출된다. 부모의 오버로딩된 생성자들은 자식의 생성자에서 호출 가능한데, 자식 생성자 옆에 : base() 를 사용하여 base안에 원하는 매개변수를 집어넣는 것으로 호출할 수 있다. 지금까지는 생성자에서 자신의 필드에 접근할 때 this 키워드를 사용하여 접근했었다..

언어/C# 2023.09.29

c# 잡지식

생성자 더보기 생성자는 각 객체의 필드 초기화를 담당한다고 볼 수 있다. 선언은 클래스이름(){ } 으로, 반환형식이 없다. 또한 오버로딩으로 여러 타입의 생성자를 동시에 만들고, 원하는 경우의 생성자를 사용할 수 있다. (이 경우 생성자는 선택된 하나의 경우만 실행된다.) 매개변수에 아무것도 받지 않는다면 정해둔 값으로 항상 초기화 되겠지만 매개변수를 받는 경우 생성자의 초기화에서 주로 this.필드 의 형식을 사용한다. 주로 사용하진 않지만 public int a; public int b; public ClassName() { a = 10; b = 15; } public ClassName(int a) : this() // 또는 this(a) { this.a = a; } 이렇게 생성자 뒤에 : this..

언어/C# 2023.09.28

스택과 힙 메모리에는 각각 어떤 코드가 저장될까?

같은 class로 서로 다른 객체를 만들어 줄 때마다 class 안에 있는 필드들을 다르게 설정하고 싶을 때 new를 이용하여 생성해주고 다시 직접 초기화하는 작업을 반복 그럴바에 class 내부에 그 class타입의 함수를 만들어서 그 안에 객체를 생성하면 된다. class Knight { public int hp; public int attack; public Knight Clone() { Knight knight2 = new Knight(); knight2.hp = this.hp; knight2.attack = this.attack; return knight2; } } 이렇게 같은 클래스에서 서로 다른 클론들을 생성하는 것을 딥 카피라고 한다. stack에는 잠깐 계산할 때만 필요한 임시값을 저장할..

언어/C# 2023.09.28

ref, out

일반적으로 우리는 함수를 이용할 때 함수의 연산 이후 함수의 body부분에서 값을 return하고, 함수를 호출한 부분에서 그 return된 값을 따로 저장하여 사용하였다. 함수 내부의 연산은 호출이 끝나고 나면 기억되지 않지만, 함수가 끝나기 전에 return에 연산한 값을 복사하여 결과를 반환하는 방식이다. 하지만 return하여 따로 저장하기보다 값 그 자체에 접근하여 연산해야 할 필요가 있는 경우 어떻게 해야할까? ref 는 매개변수 안의 값을 복사하여 계산하는 것이 아닌 값 주소를 참조하여 계산한다. 때문에 함수를 벗어나도 매개변수 안의 값 또한 함수의 연산이 적용되어 함수 밖으로 빠져나온다. static void swap(ref int a, ref int b) { int temp = a; a ..

언어/C# 2023.09.28

열거형

switch문에서 우리는 switch (choice) { case 0: break; case 1: break; case 2: break; } 형태로 구현을 했었다. 하지만 case마다 0, 1, 2의 의미가 직관적이지 않아서 각 경우들을 바로 알 수 없었다. 그래서 코딩을 하는 경우 숫자를 넣기 보다 0에 해당하는 의미의 단어, 1에 해당하는 의미의 단어 등 우리가 알아볼 수 있는 단어로 바꿔 넣는것이 좋다. 더보기 if문의 조건같은 경우는 조건 안에 변수를 넣을 수 있지만 switch 문의 case에 들어가는 값의 경우 고정된 값을 넣어야 한다. 즉, 변수를 넣을 수 없고 상수를 넣어야 한다. ( const) 또한 String input = Console.ReadLine(); 으로 값 1을 받아오는 경..

언어/C# 2023.09.28