누군가가 새로운 프로그래밍 언어를 쓰면 어떤 언어로 쓰나요?


162

내 무지를 용서해주세요 나는 PHP로 손을 대고 발을 젖게 탐색하여 몇 년 동안 궁금해 한 질문을 강요받습니다.

완전히 새로운 프로그래밍 언어를 작성할 때 어떤 언어로 작성 합니까?

이것은 아마도 내가 존경하는 모든 프로그래머에게 어리석게 들리지만, 나는 닭고기와 계란이 난처한 일입니다. 너 뭐하니? 스스로에게 오늘 오늘 나는 새로운 언어를 발명 할 것입니다! 그리고 나서 ... 메모장? 모든 컴파일러는 기존의 언어를 기반으로 구축되었으므로, 귀찮게하는 모든 프로그래밍 언어는 궁극적으로 기초가되는 하나의 괴물 같은 가지에 만들어 질 수 있습니다 .

나의 연약한 지성으로, 나는이 매혹적인 것을 발견한다. 제발, 교육시켜주세요!

답변:


193

바보 같은 질문이 아닙니다. 훌륭한 질문입니다.

이미 대답했듯이 짧은 대답은 "다른 언어"입니다.

그렇다면 흥미로운 질문이 생길까요? 첫 번째 언어가 특정 하드웨어에 맞게 작성된 경우 어떻게됩니까? 임베디드 장치를 사용하는 사람들에게는 매우 실제적인 문제입니다. 이미 "다른 컴퓨터의 언어"로 대답했습니다. 실제로 일부 임베디드 장치는 컴파일러를 얻지 못하며 프로그램은 항상 다른 컴퓨터에서 컴파일됩니다.

그러나 당신은 그것을 더 밀 수 있습니다. 처음 작성된 프로그램은 어떻습니까?

"고수준 언어"를위한 첫 번째 컴파일러는 "어셈블리 언어"로 작성되었습니다. 어셈블리 언어는 언어의 각 명령어가 CPU에 대한 단일 명령어에 해당하는 언어입니다. 매우 낮은 수준의 언어로 작성하기에 매우 장황하고 노동 집약적입니다.

그러나 어셈블리 언어를 작성하더라도 어셈블리 언어를 "기계 언어"로 변환하려면 어셈블러라는 프로그램이 필요합니다. 우리는 더 멀리 돌아갑니다. 최초의 어셈블러는 "머신 코드"로 작성되었습니다. 컴퓨터 자체의 원시 언어와 일대일로 직접 대응되는 이진 숫자로 구성된 프로그램입니다.

그러나 여전히 끝나지 않습니다. 원시 숫자가있는 파일조차도 여전히 번역이 필요합니다. 여전히 파일에있는 원시 숫자를 컴퓨터로 가져와야합니다.

초기 컴퓨터에는 전면에 일련의 스위치가 있다고 믿습니다. 스위치가 이진수를 나타낼 때까지 스위치를 뒤집은 다음 다른 스위치를 튕겨 그 단일 번호를 컴퓨터 메모리에로드했습니다. 그런 다음 디스크 파일이나 펀치 카드에서 프로그램을 읽을 수있는 최소한의 컴퓨터 프로그램을로드 할 때까지 계속 깜박 거 렸습니다. 다른 스위치를 튕겨 프로그램 실행을 시작했습니다. 80 년대에 대학에 갔을 때 나는 그 용량을 가지고 있지만 스위치를 가진 프로그램에서 로딩 작업을 한 적이없는 컴퓨터를 보았습니다.

그리고 그보다 이전의 컴퓨터 프로그램은 플러그 보드로 고정되어 있어야 했습니다 !


20
+1, 나는이 답변이 질문의 정신에 부합한다고 생각합니다.
stderr

30
나는 한 번 Assembler II 수업을 들었고 교수는 왜 우리가 선택 과목을 선택했는지 물었습니다. 나는 "나는 쉬운 A를 원했기 때문에"우스운 대답에 갔다. 가장 좋은 대답을했다고 생각했지만 도시에 Honeywell 공장이 있고 다음 사람은 "하루 종일 마이크로 코드를 작성하고 고급 언어를 배우고 싶었습니다."라고 말했습니다.
T.Rob

3
저는 Code : 컴퓨터 언어와 소프트웨어의 숨겨진 언어를 강력히 추천 합니다. 기본적으로 진공관에서부터 고급 언어의 컴파일러에 이르기 까지이 답변과 동일한 내용을 다룹니다.
MatrixFrog

컴퓨터는 비교적 무한한 시간에도 불구하고 인간처럼 진화 해 왔습니다.
Gaurav Ojha

이제 이것은 비 건설적인 의견이 될 것이지만, 기록되어야합니다 ... 이것은 모든 형태, 형태 및 정보에 대한 훌륭한 답변입니다 :-)
Lukáš Řádek

23

가장 일반적인 답변은 C입니다. 대부분의 언어는 C 또는 콜백과 Flex 와 같은 "lexer" 및 YACC 와 같은 파서 생성기가 있는 C의 하이브리드로 구현됩니다 . 이들은 다른 언어의 구문을 설명하기 위해 한 가지 목적으로 사용되는 언어입니다. 컴파일 된 언어의 경우 C 언어로 구현 된 경우가 있습니다. 그런 다음 언어의 첫 번째 버전을 사용하여 새 버전을 만듭니다. ( 하스켈 처럼 )


1
일부 언어는 picolisp와 같이 어셈블러로 작성됩니다. ( blog.kowalczyk.info/article/picoLisp-Arc-before-Arc.html )
교수 Falken

1
lex / yacc (flex / bison) 프로그램은 어떻습니까? 이것들이 C 언어를 만들기위한 보충제로 간주됩니까?
Dave

1
가장 일반적인 답변이 C임을 증명할 것이 있습니까?
RichardOD

다음 목록을 살펴보기 시작했습니다. google.com/Top/Computers/Programming/Languages/Open_Source 그런 다음 우연히 언어 10 정도의 편집기 창을 닫았고 동기 부여가 사라졌습니다. 어쨌든, 지금까지 약 절반이 C로 구현되었고 나머지는 대부분 자체적으로 부트 스트랩됩니다.
교수 Falken

3
Lex / Yacc (또는 대안)를 언급해야한다고 생각합니다. 일반적으로 C로 언어를 작성하기 시작하지 않고 C 코드로 지원되는 어휘 분석기와 파서를 사용합니다.
Steve Rowe

14

많은 언어가 부트 스트랩 되어 있습니다 . 왜 당신이 이것을하고 싶은가에 관해서는, 종종 자신의 개밥먹는 것이 좋습니다 .

내가 참조하는 위키 백과 기사 는 닭고기와 달걀 문제 에 대해 설명 합니다 . 나는 당신이 그것을 매우 흥미로울 것이라고 생각합니다.


5
처음 시작할 때는 불가능합니다.
Michael Borgwardt

1
그렇습니다. 그러나 가능하면 많은 언어가 이런 식으로 작성됩니다. 나는 다른 사람이 없었던 것처럼 이것을 지적하고 싶었고 그것이 중요한 포인트라고 생각합니다.
RichardOD

부트 스트랩 용어를 사용하는 경우 +1 컴파일러를 두 번 컴파일해야한다는 점이 흥미 롭습니다. 처음은 분명히 맨손 컴파일러를 사용하고 두 번째는 방금 작성한 컴파일러를 사용하는 것입니다. 컴파일러에 최적화를 추가했다고 가정 해보십시오. 빌드 한 컴파일러는 이러한 최적화로 코드를 생성 할 수 있지만 최적화 컴파일러로 다시 컴파일 할 때까지 자체적으로 최적화 된 코드를 실행하지는 않습니다.
Les

@ Les- 예 부트 스트랩은 흥미로운 개념입니다.
RichardOD

2
여기에 임의의 의견. 누가 먼저 왔는지 (닭고기 또는 계란)에 관한 오래된 질문에 대한 답은 닭이 먼저 왔다는 것입니다. 그 이유는 무언가를 재생산 / 복제하기 위해서는 먼저 재생 / 복제를 수행 할 수있는 재생기 / 복제기가 있어야합니다.
SpicyWeenie

10

그래프 및 기타 복잡한 데이터 구조 작업에 적합한 언어를 사용하면 많은 것이 훨씬 쉬워집니다. 프로덕션 컴파일러는 성능상의 이유로 종종 C 또는 C ++로 작성되지만 OCaml, SML, Prolog 및 Lisp와 같은 언어는 언어 프로토 타이핑에 더 적합합니다.

언어 디자인에 사용되는 몇 가지 "작은 언어"도 있습니다. Lex 및 yacc는 예를 들어 구문 및 문법을 지정하는 데 사용되며 C로 컴파일됩니다 (ocamllex / ocamlyacc와 같은 다른 언어 및 기타 유사한 도구에 대한 포트가 있습니다).

특별한 경우, 새로운 Lisp 방언은 기존 Lisp 구현을 기반으로 구축되는 경우가 많습니다. 대부분 동일한 인프라에서 피기 백 할 수 있기 때문입니다. Scheme 인터프리터 작성은 Scheme에서 코드 페이지 아래에서 수행 할 수 있으며,이 시점에서 새로운 기능을 쉽게 추가 할 수 있습니다.

기본적으로 컴파일러는 LaTeX 소스를 DVI로 변환하고 C 코드를 어셈블리로 변환 한 다음 기계 언어로 변환하고 문법 사양을 구문 분석기의 C 코드로 변환하는 등 무언가를 읽고 다른 것으로 변환하는 프로그램입니다. 소스 형식의 구조 (구문 분석), 해당 구조의 의미, 데이터를 단순화하는 방법 (최적화) 및 생성 할 출력의 종류. 통역사는 소스를 읽고 직접 실행합니다. 통역사는 일반적으로 작성하기가 더 간단하지만 속도가 훨씬 느립니다.


4

실제로 원하는 거의 모든 언어로 쓸 수 있습니다. Ruby로 C 컴파일러를 작성하는 것을 방해하는 것은 없습니다. "모두"는 프로그램을 구문 분석하고 해당 기계 코드를 생성하는 것입니다. 파일을 읽고 쓸 수 있으면 프로그래밍 언어로 충분할 것입니다.

새 플랫폼에서 처음부터 시작하는 경우 크로스 컴파일을 수행 할 수 있습니다. Java 또는 기본적으로 x86에서 실행되는 새 플랫폼의 컴파일러를 작성하십시오. PC에서 개발 한 다음 프로그램을 새 대상 플랫폼으로 전송하십시오.

가장 기본적인 컴파일러는 아마도 Assembler와 C입니다.


그러나이 "모든"언어는 재귀 호출을 지원해야합니다. 그렇지 않으면 구문 분석기와 구문 분석기를 구현하는 것이 실제로 어려울 것입니다.

2
작업에 적합하지 않은 언어를 선택하면 자신의 잘못입니다. 컴파일러 / 인터프리터 만이 아닌 모든 프로젝트에서 발생할 수 있습니다.
ziggystar

4

기술적으로 "새로운 프로그래밍 언어 작성"에는 코드가 포함되지 않습니다. 언어의 모양과 작동 방식에 대한 사양을 제공합니다. 귀하의 언어가 어떤 것인지 알면 통역사와 통역사를 작성하여 실제로 언어를 "일"하게 할 수 있습니다.

번역기는 한 언어로 프로그램을 입력하고 다른 언어로 동등한 프로그램을 출력합니다. 인터프리터는 어떤 언어로 프로그램을 입력하고 실행합니다.

예를 들어, C 컴파일러는 일반적으로 C 소스 코드 (입력 언어)를 어셈블리 언어 프로그램 (출력 언어)으로 변환합니다. 그런 다음 어셈블러는 어셈블리 언어 프로그램을 가져 와서 기계 언어를 생성합니다. 출력이 완료되면 번역가가 프로그램을 실행할 필요가 없습니다. 이제 기계어 프로그램이 있으므로 CPU가 인터프리터 역할을합니다.

많은 언어가 다르게 구현됩니다. 예를 들어, javacJava 소스 코드를 JVM 바이트 코드로 변환하는 변환기입니다. JVM은 Java 바이트 코드를 실행하는 인터프리터 [1]입니다. 실행 javac하고 바이트 코드를 얻은 후에 는 javac더 이상 필요 하지 않습니다. 그러나 프로그램을 실행할 때마다 JVM이 필요합니다.

번역가가 프로그램을 실행하기 위해 곁에있을 필요가 없다는 사실은 다른 언어의 "상위"레이어와 레이어를 실행하지 않고도 언어를 "부트 스트랩"할 수있게하는 것입니다.

[1] 대부분의 JVM은 배후에서 번역을 수행하지만 JVM에 대한 인터페이스가 "입력 언어-> 출력 언어"가 아니라는 점에서 실제로 번역가는 아닙니다.


3

일반적으로 원하는 언어를 거의 사용할 수 있습니다. 예를 들어 PHP는 C로 작성되었습니다. 컴파일러에 액세스 할 수없는 경우 어셈블리 언어를 작성하고이를 수동으로 기계어 코드로 컴파일해야합니다.


2
머신 코드를 컴파일 할 필요는 없습니다. 정의상 CPU의 모국어입니다.
Stu Thompson

1
진실. 내가 말하고자하는 것은 "조립 언어 나 그와 비슷한 것으로 기계어 코드를 컴파일하는 것"이었다. 나는 틀릴 수 있지만 소수의 사람들이 코드를 이진 / 16 진수로 바로 입력한다고 생각합니다.
Kaivosukeltaja

2

많은 언어가 먼저 다른 언어로 작성된 다음 자체적으로 다시 구현되고 그 방식으로 부트 스트랩되었습니다 (또는 PHP 및 perl과 같은 외국어로 구현을 유지했습니다). 그러나 첫 번째 어셈블러와 같은 일부 언어는 기계 코드로 수동 컴파일되었습니다 첫 번째 C- 컴파일러는 수동으로 어셈블리로 컴파일되었습니다.

나는 그것에 대해 읽은 이후로 부트 스트랩에 관심이 있었다. 더 많은 것을 배우기 위해 나는 EBF 라고 불리는 BF의 자체 슈퍼 세트를 작성하여 스스로 시도했습니다 . EBF의 첫 번째 버전에는 3 개의 추가 프리미티브가 있었고 첫 번째 바이너리를 직접 컴파일했습니다. 그렇게 할 때 2 단계 리듬을 발견했습니다. 한 릴리스에서 현재 언어로 기능을 구현했으며 구현 된 기능을 활용하기 위해 코드를 다시 작성하는 달콤한 릴리스가있었습니다. 이 언어는 LISP 인터프리터 를 만드는 데 사용될 정도로 표현력이 풍부했습니다 .

첫 번째 릴리스 태그 의 소스와 함께 손으로 컴파일 된 버전이 있으며 코드가 매우 작습니다. 마지막 버전은 크기와 코드가 12 배 더 크며 더 작은 코드를 허용하므로 현재 버전을 직접 컴파일하기가 어렵습니다.

Edmund Grimley Evans는 그의 HEX 언어 와 비슷한 일을 했습니다.

이 작업을 수행하는 데 흥미로운 점 중 하나는 왜 어떤 것이 있는지 이해한다는 것입니다. 내 코드는 작은 증분 조정 인 경우 처음부터 설계된 것이 아니라 진화 된 것처럼 보이는 제품이었습니다. 오늘 코드를 읽을 때이 점을 염두에 두십시오.


1

일반적으로 시스템 개발에 적합한 범용 프로그래밍 언어 (예 : C, Haskell, ML, Lisp 등)가 있지만 옵션 목록은 길다. 또한 일반적으로 언어 구현을위한 일부 도메인 별 언어 (예 : 파서 ​​및 어휘 분석기 생성기, LLVM 과 같은 중간 언어 등) 및 일부 쉘 스크립트, 테스트 프레임 워크 및 빌드 구성 시스템 (예 : autoconf)이 있습니다.


1

C가 아니라면 대부분의 컴파일러는 C 또는 AC와 같은 프로그램이었습니다. 그런 다음 어셈블리 lang이 갈 길입니다. 그러나 새로운 lang을 처음부터 작성할 때 프로토 타입 언어의 매크로 라이브러리 또는 소스 코드가 없으면 자신의 함수를 정의해야합니다 이제 어떤 언어로? Fortran 기본 알고리즘 리스프와 같은 객체 지향 구조화 된 언어 사양에서 bnf 문법처럼 보이는 psedocode라는 소스 코드 형식을 기계에 작성할 수 있습니다. 따라서 이러한 언어 구문과 유사한 크로스 코드를 작성하는 이미지 psedo 코드


1
psedo 코드가 기계 판독 가능해야한다고 생각하지 않습니다
Richard Tingle

0

더 많은 바이너리 또는 어셈블리 작업은 함수, 즉 어셈블러 / 컴파일러 작업, 데이터 및 함수에서 객체로 변환해야합니다 (소스 파일이없는 경우) 언어 구현, 그런 다음 "참조"구현을 인식하거나 많은 지식이 필요한 자체 기능, 절차 및 데이터 구조를 정의해야하며, 기능이 무엇인지 스스로에게 물어봐야합니다. 그러면 마음이 언어 시뮬레이션이됩니다. 이것은 마스터 프로그래머를 나머지와 분리시킵니다.


0

나는 몇 달 전에이 질문을했다. 그리고 나는 기사를 거의 읽지 않고 soft라는 언어를 쓰는 데 도움이되는 비디오를 보았습니다. 아직 완성되지는 않았지만이 여행에서 많은 것을 배웠습니다.

알아야 할 기본 사항은 코드 조각을 실행해야 할 때 컴파일러가 작동하는 방식입니다. 컴파일러에는 어휘 분석, 시맨틱 분석기, AST (Abstract Syntax Tree) 등과 같은 많은 단계가 있습니다.

새 언어로 내가 한 일은 여기에서 찾을 수 있습니다-http: //www.singhajit.com/writing-a-new-programming-language/

당신이 처음으로 언어를 쓰고 있다면, 최선을 다하고 갈 길이 멀다.


0

일반적으로 프로그래밍 언어는 무엇입니까?

프로그래밍 언어는 컴퓨터와 대화하는 유일한 방법입니다. 대략 컴퓨터는 0과 1 만 이해할 수 있기 때문에 (컴퓨터는 두 개의 상태만을 취할 수있는 스위치로 트랜지스터로 만들어 졌기 때문에이 두 상태를 0과 1이라고 부릅니다.) 우리는 인간으로서 컴퓨터 과학자들이 바이너리 (0,1)의 모든 명령에서 좀 더 인간이 읽을 수있는 형태로 어셈블리 언어라고 일대일로 매핑하기로 결정했습니다.

예를 들어 다음과 같은 명령이 있다면 :

11001101

어셈블리에서는 다음과 같이 호출됩니다.

LOAD_A 15

이것은 레지스터 a의 내용을 메모리 위치 15에로드하는 것을 의미합니다. 내가 말했듯이 트랜지스터의 두 상태 또는 컴퓨터의 다른 것에 대해 0과 1을 선택하는 것과 같은 관습이라고 생각합니다. 어셈블리 언어를 기억하는 것이 더 쉬울 것입니다. 따라서 사용자는 어셈블리 코드를 작성하고 일부 프로그램 (이 경우 어셈블러)은 코드를 이진 명령어 또는 기계 언어로 변환합니다.

그러나 매일 컴퓨터가 개선되면서 10000과 같은 더 많은 지침을 가진 더 복잡한 프로그램을위한 공간이있었습니다.

이 경우 어셈블리와 같은 일대일 매핑이 작동하지 않으므로 다른 고급 프로그래밍 언어가 만들어졌습니다. 그들은 예를 들어 사용자가 만든 화면에 무언가를 인쇄하기 위해 I / O 장치와의 관계가 약 80 개의 지시 사항을 취한다면 여기에서 무언가를 수행 하고이 코드를 하나의 라이브러리에 패키지하고 printf와 같이 호출 할 수 있다고 말했습니다. 또한이 printf를 관련 어셈블리 코드로 변환 할 수있는 다른 프로그램을 작성하면 어셈블리가 나머지를 수행합니다. 그래서 그들은 그것을 컴파일러라고 부릅니다.

이제 화면에 무언가를 인쇄하려는 모든 사용자는 바이너리 또는 어셈블리로 모든 명령을 작성할 필요가 없으며 printf ( "something")을 입력하면 컴파일러 및 어셈블러와 같은 모든 프로그램이 나머지를 수행합니다. 나중에 다른 긴 코드는 같은 방식으로 패키지되어 다른 사람들의 작업을 용이하게합니다. 파이썬에서 수천 줄의 코드를 하나의 코드로 단순화하고 다른 사람들의 사용을 위해 포장 할 수 있음을 알 수 있습니다.

그래서 파이썬으로 많은 다른 코드를 압축하고 모듈 (libray, package 또는 호출하려는 것)을 만들었고 그 모듈을 mgh (내 이름)라고 부릅니다. 이제 우리가 어떻게 든이 mgh를 만들었습니다.

import mgh
mgh.connect(ip,port.data)...

지정된 IP 및 포트 번호를 사용하여 원격 서버에 쉽게 연결하고 나중에 데이터를 전송할 수 있습니다. 이제 사람들은 한 줄을 사용하여 모든 작업을 수행 할 수 있지만 mgh 파일에서 검색 된 많은 코드가 실행되고 있습니다. 패키징은 실행 프로세스 속도를 높이기위한 것이 아니라 다른 프로그래머의 작업을 용이하게합니다. 따라서 여기에서 누군가가 코드를 먼저 사용하려면 파일을 가져온 다음 파이썬 인터프리터가 코드의 모든 코드를 인식하므로 코드를 해석 할 수 있습니다.

이제 프로그래밍 언어를 만들고 실행하려면 먼저 번역이 필요합니다. 예를 들어 구문을 이해하고 c로 변환 할 수있는 프로그램을 작성한다고 가정합니다 (이 경우에는 번역 된 후). c에서 나머지는 c 컴파일러에 의해 처리 된 다음 어셈블러, 링커 등에 의해 처리됩니다. 비록 c로 먼저 변환되어야하기 때문에 더 느린 가격을 지불해야 할지라도.

이제 당신이 할 수있는 또 하나의 일은 c와 마찬가지로 모든 코드를 동등한 어셈블리 언어로 번역 할 수있는 프로그램을 만드는 것입니다. 그러나이 경우 프로그램은 직접 수행 할 수 있으며 나머지는 링커. 이 프로그램을 컴파일러라고합니다.

그래서 내가 이야기하고있는 것은 시스템이 이해하는 유일한 코드는 0,1이므로 어쨌든 구문을 변환해야합니다. 이제 운영 체제에서 어셈블러, 링커 및 ...와 같은 다양한 프로그램이 있습니다. 코드를 어셈블리로 변환 할 수 있다면 나머지를 처리 ​​할 수 ​​있거나 코드를 해당 언어로 변환하여 다른 프로그래밍 언어 컴파일러를 사용할 수도 있다고 말한 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.