2009-05-01 6 views
0

실제 작업을 수행하는 것 외에도 가려움증이 있습니다. 가려운 것은 다른 언어 (템플릿 툴킷/펄)에서 템플릿 시스템을 가깝게 모방 한 뷰 엔진을 작성하는 것입니다. 이것은 내가 시간이 있다면 그것 중 하나입니다/새로운 종류의 프로젝트를 배우기 위해 그것을하십시오.TemplateLanguage/VewEngine 작성

저는 CoCo/R과 ANTLR을 보면서 시간을 보냈습니다. 솔직히 내 머리가 아팠지만 CoCo/R의 일부가 침몰하고 있습니다. 불행히도 대부분의 예제는 소스를 읽는 컴파일러를 만드는 것에 관한 것입니다. 코드는 없지만 템플릿 용 프로세서를 만드는 방법은 다루지 않습니다.

그래, 그것들은 똑같지 만, 실제 코드가 파싱되어 실행되는 것이 아니라 소스의 대부분이 html 인 템플릿 용 언어를 정의하는 방법을 고집하지 않을 수 없습니다.

이런 종류의 좋은 초보자 리소스가 있습니까? 나는 스파크에 간수를 데려 갔는데, 레포에 문법이없는 것처럼 보였다.

어쩌면 그게 과도 함이며, 파일에서 템플릿 구문을 C#으로 테스트하고 바꿀 수 있습니다. http://msdn.microsoft.com/en-us/magazine/cc136756.aspx#S2

신발을 신고 언어 전문가가 아니 셨다면 어디에서 시작 하시겠습니까?

답변

3

Spark 문법은 유창한 도메인 특정 언어로 구현됩니다.

몇 개의 레이어로 선언되었습니다. html 구문을 인식하는 규칙은 MarkupGrammar.cs에 선언되어 있습니다.이 규칙은 xml 사양에서 직접 복사 한 문법 규칙을 기반으로합니다.

마크 업 규칙은 CodeGrammar.cs에 선언 된 csharp 구문 규칙의 제한된 하위 집합을 의미합니다. Spark는 문자열 주위에 작은 따옴표를 조정하여 큰 따옴표로 묶는 등의 작업 만 수행하면됩니다.

개별 규칙 자체는 ParseAction<TValue> delegate이고 Position을 허용하고 ParseResult을 반환합니다. ParseResult는 액션에 의해 파싱 된 TValue 데이터 항목과 TValue를 생성 한 콘텐츠를 지나쳐 진 새로운 Position 인스턴스를 포함하는 간단한 클래스입니다.

small number of operators에 설명되어있는 것처럼 하나의 구문 분석 작업을 결합하여 다양한 구문 구문의 모양에 대한 매우 자세하고 강력한 표현을 작성할 수있는 small number of operators을 소개하기 전에는 그다지 유용하지 않습니다.

파견 작업으로 대리인을 사용하는 기술은 Luke H의 블로그 게시물 Monadic Parser Combinators using C# 3.0에서 가져 왔습니다. 나는 또한 Creating a Domain Specific Language for Parsing에 대한 게시물을 썼다.

원하는 경우 Spark.dll 어셈블리를 참조하고 기본 CharGrammar의 클래스를 상속하여 특정 구문에 대해 완전히 새로운 문법을 만들 수도 있습니다. 아마도이 기술로 실험을 시작하는 가장 빠른 방법 일 것이고 그 예는 CharGrammarTester.cs에서 찾을 수 있습니다.

0

단계 1. 정규 표현식 (정규 표현식 대체) 예를 들어,

hel<b>lo[if foo]bar is [bar].[else]baz[end]world</b>! 

2 단계

write('hel<b>lo') 
if('foo') 
write('bar is') 
substitute('bar') 
write('.') 
else() 
write('baz') 
end() 
write('world</b>!') 

하려면 토큰을 변환 분할, 토큰 목록에 입력 템플릿 문자열을 분할 구문 트리에 나열하십시오.

* Sequence 
** Write 
*** ('hel<b>lo') 
** If 
*** ('foo') 
*** Sequence 
**** Write 
***** ('bar is') 
**** Substitute 
***** ('bar') 
**** Write 
***** ('.') 
*** Write 
**** ('baz') 
** Write 
*** ('world</b>!') 

class Instruction { 
} 
class Write : Instruction { 
    string text; 
} 
class Substitute : Instruction { 
    string varname; 
} 
class Sequence : Instruction { 
    Instruction[] items; 
} 
class If : Instruction { 
    string condition; 
    Instruction then; 
    Instruction else; 
} 

단계 3. 다음과 같은 재귀 함수 reter)를 사용하면 트리를 걸어서 지시 사항을 실행할 수 있습니다.

언어가 eval() (예 : Perl, Python, Ruby)을 지원하는 경우 다른 방법 (1 ~ 3 단계 대신) : regexp 대체를 사용하여 템플릿을 eval() 가능한 문자열 호스트 언어로 eval()을 실행하여 템플릿을 인스턴스화합니다.

+0

음, 처음 3 단계는 본질적으로 ANTLR/COCO/R입니다. 자신의 파서를 굴리거나 문법에 의존하는 문제입니다. 대안은 제가 머리를 감쌀 수있는 것입니다. (템플릿을 C# 출력으로 변환하십시오. 시작할 때 가장 쉬운 방법과 가장 좋은 방법은 무엇입니까? 결국 테스트는 이런 종류의 일에 왕이됩니다 – claco

+0

단계 2는 ANTLR과 COCO/R과 비슷하다. 나에게 가장 좋은 방법은 가능한 한 간단하게 만드는 것이다. 예를 들어 if 조건이 산술 표현식을 지원할 필요가없는 경우 (예 : [if 3 * 4> 10]) ANTLR이나 COCO/R은 필요하지 않습니다. 템플릿을 왼쪽에서 오른쪽으로 스캔하고 보류중인 ifs를 스택에 넣을 수 있습니다. 따라서 [끝]이 표시되면 무엇을 닫아야 하는가? – pts

0

할 일이 많습니다. 하지만 그것은 간단한 GET 문과 테스트를 통해 작동합니다. 시작입니다.

http://github.com/claco/tt.net/

는 결국, 나는 이미 loudejs '방법 갈 줄 수 ANTLR에 너무 많은 시간을 보냈습니다. 나는 파서/렉서보다는 전체 과정에 조금 더 많은 시간을 보내고 싶었다. 어쩌면 버전 2에서 나는 두뇌가 좀 더 이해할 때 스파크 방식으로 갈 수 있습니다.

0

Vici Parser (이전의 LazyParser.NET)은 시작하는 데 도움이되는 오픈 소스 토큰 화/템플릿 파서/표현 파서입니다.

당신이 원하는 것이 아니라면, 소스 코드를보고 아이디어를 얻을 수 있습니다.