프로그래밍 언어 란 정확히 무엇입니까? 그러한 언어로 쓸 수있는 것은 무엇입니까?


26

좋아, 나는 프로그래밍을 처음 접했고 이것이 상당히 추상적 인 질문이라는 것을 인정한다.

사람들이 서로를 이해할 수 있기 때문에 우리가 매일 말하는 자연 언어가 존재합니다. 컴퓨터가 특정 언어로 작성된 코드를 어떻게 이해할 수 있습니까?

A 씨가 새로운 언어를 만든다고 해봅시다. 기계에 의해 어떻게 받아 들여 집니까? 제작자가 기계 언어를 사용하여 기계와 통신하여 새로운 언어를 만들어야합니까? 기계가 올바르게 이해하면서 언어로 쓸 수있는 것은 무엇입니까?


1
그러한 언어로 쓸 수있는 것은 무엇입니까? - "브레인 : 새로운 원더 헤드 필러!" 스파이크 밀리건
Stephen C

6
그럼에도 불구하고 약간 광범위하지만 좋은 질문입니다. 너무 많은 사람들이 어떻게 작동하는지 궁금하지 않고 단순히 언어를 사용합니다. 호기심이 많았습니다.
riwalk

4
이것은 Wikipedia 가 쉽고 간단하게 대답 하는 일반적인 참조 질문 입니다.
Aaronaught

답변:


39

"컴파일러" 라는 단어를 사용하여 일련의 질문에 대한 전체 답변을 요약 할 수 있습니다 . 컴파일러는 소스 코드를 입력으로 사용하고 언어 디자이너가 결정한 언어 규칙을 적용하여 코드의 의미를 알아 내고 다른 언어에서 출력과 같은 의미의 코드를 생성하는 기능을 가진 특수 프로그램입니다. 코드는 다른 고급 언어로 변환하는 특수 컴파일러가 있지만 일반적으로 머신 코드 또는 바이트 코드 형식 (가상 머신의 "머신 코드")입니다. 그러나이 질문의 범위를 벗어납니다.

모든 언어에 컴파일러가있는 것은 아닙니다. 그중 일부는 대신 인터프리터 를 가지고 있는데, 이는 프로그램이 의미하는 것을 결정한 후 기계 코드를 생성하는 대신 단순히 프로그램을 즉시 실행한다는 점을 제외하고 컴파일러와 동일한 작업을 수행합니다. 그러나 코드를 구문 분석 (읽기)하고 의미를 결정하는 기본 원칙은 동일합니다.

이것보다 더 깊이 대답하면 컴파일러 이론에 들어갈 수 있습니다. 이는 매우 광범위한 주제입니다. 이 주제에 관심이 있으시면 "컴파일러"에 대한 Wikipedia 기사를 읽고 링크를 확인하십시오. 구체적인 질문이 있으시면 여기에서 질문하십시오.


11
+1-또한 새로운 언어를 작성할 때는 다른 언어로 컴파일러 나 인터프리터를 작성해야한다고 덧붙입니다. 그런 다음 최신 버전의 컴파일러 또는 인터프리터를 이전 버전의 언어로 작성하고 이전 컴파일러로 컴파일 할 수 있습니다. 최초의 어셈블러는 기계어 코드로 작성되었습니다. 첫 번째 C 컴파일러는 등 조립 (대부분)에서 작성되었습니다
스콧 위트 락을

1
컴파일러의 정의를 변경합니다. 그들은 모두 기계 코드를 방출하지는 않습니다. 특히 오늘날에는 MSIL과 같은 "중간 코드"를 방출하는 많은 컴파일러가 있습니다. JavaScript를 생성하는 컴파일러도 있습니다!
Neil N

3
초보자에게 설명 할 때조차도 컴파일러가 정의에 따라 기계 코드를 생성한다고 주저합니다. 그것은 함수가 실수, 무의미한 과도한 단순화를 반환한다고 말하는 것과 같습니다. 모든 컴파일러 구성은 실제로 실리콘으로 구축 된 컴퓨터 용이 아닌 추상적으로 만 정의 된 코드 (VM 또는 고급 언어)를 생성 할 때 유지됩니다 .C 표준이 추상 시스템을 정의한다고하는 이유 가 있습니다. A는 컴파일러 길래로 매우 낮은 수준 LLVM IR '자바 스크립트)에서이. 초보자는 빨리 얻을수록 좋습니다.

2
대부분의 컴파일러 서적에서 사용하는 단순화는 컴파일러가 언어 규칙을 적용하여 소스 언어에서 대상 언어로 출력으로 변환하는 것입니다. (특히 입문 과정을 위해 C로 컴파일하는 것은 드문 일이 아닙니다).
JasonTrue

4
@delnan, 훨씬 더-모든 언어 자체 추상 기계를위한 기계어 코드 입니다. 언어의 수준이 아무리 높아도
SK-logic

11

지적했듯이, 인간은 영어, 프랑스어, 독일어와 같은 "자연"언어를 통해 서로 의사 소통합니다. 그것들은 의도적으로 발명하기보다는 자연스럽게 획득하기 때문에 자연이라고 불립니다 (에스페란토는 예외 임).

공식 언어는 어떤 목적이나 다른 목적으로 개발 된 언어입니다. 예를 들어 C와 같은 프로그래밍 언어는 컴퓨터 프로그래밍을 위해 고안된 공식 언어입니다.

모든 언어는 문법을 사용하여 설명 할 수 있습니다. 문법 계층은 1956 년 Noam Chomsky에 의해 설명되었습니다. 다음과 같은 수준으로 구성됩니다.

유형 0 문법 (제한되지 않은 문법). 그것들은 가장 일반적이며 Turing Machine과 동일합니다. 따라서 주어진 문자열이 제한되지 않은 문법의 일부인지를 결정하는 문제는 결정할 수 없습니다.

유형 -1 문법 (문맥에 맞는 문법) 영어와 같은 거의 모든 자연 언어는 상황에 따라 다릅니다. 영어에서 문맥 감도의 예는 "화살표처럼 날아갑니다"라는 두 문구입니다. "과일은 바나나처럼 날아갑니다." 일반적으로 컴퓨터가 상황에 맞는 언어를 이해하기 어렵습니다.

유형 -2 문법 (문맥이없는). 문맥없는 언어는 대부분의 프로그래밍 언어의 구문에 대한 이론적 근거입니다.

유형 3 문법 (정규 문법) 정규 언어 패밀리는 정규 표현식으로 얻을 수 있습니다. 정규 언어는 일반적으로 검색 패턴과 프로그래밍 언어의 어휘 구조를 정의하는 데 사용됩니다.

유형 2 (문맥이없는)와 유형 3 (정규) 문법은 파서가 효율적으로 구현 될 수 있기 때문에 컴퓨터에서 가장 자주 사용됩니다.

BNF (Backus Normal Form 또는 Backus–Naur Form) 는 문맥없는 문법에 대한 표기법으로, 종종 컴퓨팅에 사용되는 언어의 구문을 설명하는 데 사용됩니다.

예를 들어 식별자는 다음과 같이 설명 될 수 있습니다.

<identifier> ::= <letter> { <letter> | <digit> }

즉, 문자로 시작해야하며 추가 문자 나 숫자를 포함 할 수 있습니다.

이전에는 문자가 'a'| 'b'| 'c'등이 있으며 숫자는 동일한 유형의 표기법을 사용하여 '0'에서 '9'로 정의됩니다.

AC "for"문은 다음과 같이 정의 될 수 있습니다.

 <for_statement> ::=
    'for' '(' <expression> ';' <expression> ';' <expression> ')' <statement> 

그런 다음 어휘 분석기 및 파서 (컴파일러 또는 인터프리터의 첫 단계)는 특정 언어에 대해 BNF에서 설명하는 특정 문법을 허용하도록 구성됩니다. 어휘 분석기는 일반적으로 언어의 다양한 토큰 (예 : 키워드, 식별자 또는 숫자)을 분리하는 데 사용되며 파서는 "for"문 구성 방식과 같이 토큰이 함께 작동하는 방식을 파악하는 데 사용됩니다. .


훌륭한 글쓰기 +1. 그러나 이것이 대답으로 받아 들여지지 않은 것은 놀랍지 않습니다. 이것이 OP가 요구한다고 생각한 것이지만, 그들이 선택한 대답을 바탕으로 훨씬 높은 수준의 무언가를 원한 것 같습니다.
Matthew Rodatus

5

먼저 "언어"를 정의하자. 언어에는 먼저 어휘 (통신의 대상인 개념을 정의하는 단어 목록)와 구문 (통신의 구조를 정의하는 "프라이머"또는 규칙 집합)이 필요합니다.

가장 기본적인 수준에서 C #은 영어와 다르지 않습니다. C #을 "프로그래밍 언어"로 만드는 이유는 의도와 디자인입니다. 개별 하위 레벨 명령으로 요약되도록 설계되었습니다. 따라서 사전 정의 된 어휘가 제한되고 구문이 매우 엄격하게 적용되며 "청중"(컴퓨터;보다 정확하게는 컴파일러를 통해 잘 알려진 사전 정의 된 방식으로 전체 언어를 사용하도록 설계됨) 소스 코드를 간단한 명령의 "중급 언어"로 번역 한 다음 "런타임"에 의해 기계 코드로 추가로 번역 할 수 있습니다. C #에서는 산문이나시를 쓰지 않습니다. 컴퓨터에게 가능한 가장 명확한 방법으로 작업을 수행하도록 지시합니다.

컴퓨터의 경우, 일반적으로 컴파일러라고하는 도구가 코드로 작성한 것을 컴퓨터가 사용할 수있는 명령어로 변환하는 데 필요합니다. 대부분의 기술과 마찬가지로 컴퓨터 과학은 본질적으로 반복적 인 "계층화 된"프로세스입니다. 컴퓨터가 처음 발명되었을 때 수동으로 이진 명령어를 입력하여 프로그래밍했습니다. 이러한 명령어는 각 프로세서에 대해 16 진 "기계 코드"로 표준화되었습니다. 차이점은 사람에게 표시하기 위해 이진 숫자를 그룹화하는 방법에만 있습니다. 그런 다음 어셈블러 코드에서 명령 목록 및 레지스터 이름과 같은 일부 기본 식별자는 프로그램을 작성할 때 16 진수 코드로 대체되었습니다. ASM은 여전히 ​​1 : 1을 기본 기계 코드로 변환 할 수 있습니다. 양자 도약은 3 세대 "제국적인"프로그래밍으로 기본적으로 변수 및 논리 루프와 같이보다 이해하기 쉬운 추상적 개념을 사용하여 키워드 및 구문을 기반으로하는 패턴을 사용하여 기본 명령어로 요약합니다. COBOL, FORTRAN, Pascal 및 C와 같은 초기 언어는 사람이 특정 기계 언어 (일반적으로 8086 ASM)로 "번역"할 수 있습니다. 그런 다음 객체 지향 프로그래밍의 혁명이 일어났습니다. 기본적으로 코드는 상태와 논리가 결합 된 "객체"에 개념적으로 캡슐화되는 것으로 정의하는 추가 구문 규칙입니다. 인간이 특정 기계 언어 (보통 8086 ASM)로 그런 다음 객체 지향 프로그래밍의 혁명이 일어났습니다. 기본적으로 코드는 상태와 논리가 결합 된 "객체"에 개념적으로 캡슐화되는 것으로 정의하는 추가 구문 규칙입니다. 인간이 특정 기계 언어 (보통 8086 ASM)로 그런 다음 객체 지향 프로그래밍의 혁명이 일어났습니다. 기본적으로 코드는 상태와 논리가 결합 된 "객체"에 개념적으로 캡슐화되는 것으로 정의하는 추가 구문 규칙입니다.

오늘날 우리는 "4 세대"언어에 잘 들어갑니다. 언어는 기계에 직접 연결하지 않고 다른 프로그램과의 통신을 정의하기 위해 작성된 언어입니다. 여기에는 XML / HTML과 같은 "마크 업"언어, JavaScript 및 SQL과 같은 "스크립팅"언어, Java 및 .NET Framework와 같은 "샌드 박스"언어의 대부분이 포함됩니다 (IL로 컴파일 된 후 더 자세히 해석 됨) 머신 및 플랫폼 별 세부 정보를 추상화하는 런타임). 또한 기능별 프로그래밍 언어 영역을 포함한다고 말할 수 있는데, 이는 기계 별 세부 사항뿐만 아니라 작업 별 세부 사항의 추상화를 제공하기 위해 런타임에 크게 의존합니다. 이 4 세대 언어는 사람이 기본 기계 명령어로 번역하는 것이 거의 불가능합니다. 그리고 요점은 그것이 가치있는 노력이 아니라는 것입니다. 이러한 언어의 강점은 계층화 된 프로세스로, 결국 컴퓨터에 낮은 수준에서 수행 할 작업을 알려주는 데 사용됩니다.


감사. 프로그래밍 언어 진화의 역사를 엿볼 수 있습니다.
Erica Xu

2
@KeithS : 좀 더 읽기 쉽도록 마지막 단락의 서식을 다시 지정할 수 있습니다.
Ivan Vučica

4

좋은 질문입니다. 정답은 "컴퓨터 과학"의 절반을 형성합니다.

스타터를 위해, 나는 통해 감추고 권 해드립니다 denotational운영 의미하고 읽는 이 책을 . 프로그래밍 언어가 무엇인지, 공식적으로 정의 할 수있는 방법에 대해 어느 정도 이해합니다.

위의 내용이 너무 학문적이라면 Petzold, "Code" 로 시작한 다음 시맨틱 스로 돌아갈 수 있습니다.


1
당신은 18 yo 멍청한 놈 이이 질문에 대답하기 위해 무거운 이론을 읽을 것으로 정말로 기대합니까?
Job

2
@Job, 그의 이전 질문에 따르면, 그는 대학에서 Scheme (그리고 아마도 SICP)을 복용하고 있습니다. 그렇다면 약간의 의미론이 좋을 것입니다. 어쨌든이 이론에 대한 이론 없이는이 질문에 대한 적절한 답이 없습니다.
SK-logic

"코드"를 언급 한 +1 이 책은 모든 초급 CS 학생에게 반드시 읽어야합니다.
Daniel Pryden

4

프로그램을 프로그래밍 언어로 작성하면 다른 프로그램이 프로그램의 기호를 컴퓨터가 이해하는 기호로 변환합니다. 때로는 여러 단계가 필요합니다. 예를 들어 C에서 :

  1. 사용자는 CPU가 이해하지 못하지만 프로그래머가 직접 이해하는 고급 언어 (C)로 프로그램을 작성합니다 (우리는 희망합니다!).

  2. 컴파일러는 C를 Assmebly 언어로 변환합니다.이 언어는 CPU에서 직접 이해하지 못하지만 다른 것으로 쉽게 변환 할 수 있습니다.

  3. 어셈블러는 어셈블리를 CPU가 직접 이해하는 일련의 이진 코드로 변환합니다. 일부 컴파일러는 위의 단계 (2 단계)를 건너 뛰고 소스 코드에서 직접 컴파일 된 바이너리를 생성합니다.

컴퓨터가 프로그램을 이해하도록하기 위해 컴파일러 또는 인터프리터는 오류를 발생시키고 일반적으로 구문 오류와 같이 컴파일 할 수없는 무언가가 발생하면 중지됩니다. 프로그램을 컴파일 할 수 없으면 프로그램이 프로그램을 실행하려고 시도하고 프로그램을 "이해하지"않았기 때문에 실패 할 수있는 단계에 도달 할 수 없습니다.

새 언어를 만들려면 먼저 고급 언어를 디자인 한 다음 새 언어의 심볼을 CPU가 이해하는 어셈블리 언어 명령에 매핑하는 방법을 찾아야합니다.


2
실제로는 아닙니다. 최신 컴파일러는 2 단계를 수행하지 않고 이진 코드를 직접 생성합니다. 그러나 어쨌든 어셈블리와 이진 코드는 거의 동일합니다. 매우 충실하게 분해 (이진 코드를 어셈블리로 다시 변환) 할 수 있습니다.
MSalters
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.