실수로 멋진 HTML 전처리기를 작성한 방법
4391 단어 compilerscorgiwebdevjavascript
확인.
컴파일러를 작성하려면 세 가지 주요 부분이 있습니다. Lexer, Parser 및 코드 생성기. Java 및 C#을 비롯한 다양한 언어로 이 프로젝트를 시작했지만 성공적인 구현은 현재 JavaScript로 이루어지고 있습니다.
1) 렉싱
Lexing 또는 Lexical Analysis 프로세스는 이 프로세스의 나머지 부분에 비해 실제로 매우 간단합니다. 다음 코드를 고려하십시오.
const hello = "Hello, " + "World!";
const sum = 4 + 5;
코드 조각을 렉싱할 때 전체 소스를 살펴보고 문자열을 토큰 모음으로 변환해야 합니다. 토큰은 소스 코드의 작은 조각에 대한 정보를 저장하는 간단한 구조입니다. 내가 작성한 렉서에는
Keyword
, Word
, String
및 Symbol
의 네 가지 주요 토큰 유형을 사용합니다. 따라서 위의 코드는 렉싱 후 다음과 같이 보일 수 있습니다.Keyword<"const">
Word<"hello">
Symbol<"=">
String<"Hello, ">
Symbol<"+">
String<"World">
Symbol<";">
Keyword<"const">
Word<"sum">
Symbol<"=">
Word<"4">
Symbol<"+">
Word<"5">
Symbol<";">
여기까지 했다면 Awesome!
내 프로젝트인 Mantle은
mantle.lexer.Lexer
라는 확장할 수 있는 추상 클래스를 통해 이 슈퍼*를 수행하도록 합니다. 키워드, 기호 및 문자열 구분 기호 목록을 정의하고 주석을 허용할지 여부를 지정하고 문자를 단어에 사용할 수 있는지 정의하는 함수를 전달하기만 하면 됩니다. 그런 다음 위의 목록을 만드는 것은 Lexer.parse()
를 호출하는 것만큼 쉬워지지만 계속 진행하면 직접 parse()
를 호출하지 않을 것입니다.맨틀에 대한 자세한 내용은 https://github.com/Nektro/mantle.js에서 확인할 수 있습니다.
2) 파싱
이것은 어려운 부분입니다.
구문 분석을 위해서는 토큰 목록을 단일 노드로 압축할 수 있는 토큰 패턴을 파악해야 합니다. 이것은 제대로 되기까지 많은 시행착오를 겪었고, 이 프로젝트가 그렇게 오래 걸린 주된 이유입니다.
예를 들어 위에 있는 코드의 경우 다음 규칙을 정의할 수 있습니다.
Add <= String + String
Add <= Integer + Integer
AssignmentConst <= const Word = Add
StatementList <= Add Add
더 복잡한 규칙이 있을수록 내가 곧 발견한 더 복잡한 언어가 있습니다.
mantle.parser.Parser
에 대한 JSON 예제는 https://github.com/Nektro/mantle.js/blob/master/langs/mantle-json.js에서 찾을 수 있습니다.3) 코드 생성
이는 추상 구문 트리라고도 하는 최종 압축 노드를 통과하고 새 출력을 얻을 때까지 모두 처리하는 프로세스입니다
toString()
.Note:
Optimization of higher-level languages requires a lot more work than calling toString(), but is way above my scope
4) Corgi - 새로운 HTML 전처리기
이 시점에서 나는 황홀했다. JSON 파서를 성공적으로 만들었습니다. 하지만 조금 더 복잡하게 만들고 싶었습니다. 그래서 HTML로 옮겼습니다. 그러나 문제는 HTML이 잘 구성되어 있지 않다는 것입니다. 그래서 Mantle이 파싱하기 좀 더 쉬운 버전을 만들어야겠다고 생각했습니다. 그리고 그것이 Corgi에게 온 방법입니다.
Corgi 구문은 Pug에서 영감을 받았지만 탭 기반이 아니므로 이론적으로 파일을 한 줄로 압축할 수 있습니다. Pug에서 코스메틱 HTML 태그를 사용하여 만든 탭 구조를 강제로 적용하는 것이 정말 어색하기 때문에 이 기능이 마음에 들었습니다. 따라서 Corgi는 HTML을 구조와 스타일에 적합하게 만듭니다.
Corgi 문서의 예는 다음과 같습니다.
doctype html
html(
head(
title("Corgi Example")
meta[charset="UTF-8"]
meta[name="viewport",content="width=device-width,initial-scale=1"]
)
body(
h1("Corgi Example")
p("This is an example HTML document written in "a[href="https://github.com/corgi-lang/corgi"]("Corgi")".")
p("Follow Nektro on Twitter @Nektro")
)
)
폐쇄
컴파일러를 만드는 것은 어렵지만 확실히 즐거웠습니다. 이것이 컴파일러를 이해하는 데 도움이 되기를 바랍니다.
그리고 이제 HTML Proprocessor도 가지고 있습니다. 가능한 한 많은 프로젝트에서 사용할 것입니다.
자원:
doctype html
html(
head(
title("Corgi Example")
meta[charset="UTF-8"]
meta[name="viewport",content="width=device-width,initial-scale=1"]
)
body(
h1("Corgi Example")
p("This is an example HTML document written in "a[href="https://github.com/corgi-lang/corgi"]("Corgi")".")
p("Follow Nektro on Twitter @Nektro")
)
)
나를 따르라:
Reference
이 문제에 관하여(실수로 멋진 HTML 전처리기를 작성한 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/nektro/how-i-accidentally-wrote-an-awesome-html-preprocessor-995텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)