Ragel이 정상적으로 작동합니다. 당신이 뭘 일치하는지 조심해야합니다. 귀하의 질문은 [[tag]]
과 {{tag}}
을 모두 사용하지만 귀하의 예에서는 [[tag]]
을 사용합니다. 그래서 나는 그것이 당신이 특별하다고 생각하는 것으로 생각합니다.
원하는 것은 열린 대괄호를 칠 때까지 텍스트를 먹는 것입니다. 그 괄호 뒤에 다른 괄호가 오면, 대괄호를 치기 전까지 소문자를 먹을 차례입니다. 태그의 텍스트에는 대괄호가 포함될 수 없으므로 대괄호 뒤에 올 수있는 오류가없는 문자 만 다른 대괄호로 사용됩니다. 그 시점에서, 당신은 당신이 시작한 곳으로 돌아 왔습니다.
음,이 기계의 축 어적 설명입니다 :
tag = '[[' lower+ ']]';
main := (
(any - '[')* # eat text
('[' ^'[' | tag) # try to eat a tag
)*;
까다로운 부분은 어디 당신이 당신의 행동을 부릅니까? 나는 그에게 가장 좋은 대답을 가지고 주장하지만, 여기에 내가 생각 해낸 무엇을하지 않습니다
static char *text_start;
%%{
machine parser;
action MarkStart { text_start = fpc; }
action PrintTextNode {
int text_len = fpc - text_start;
if (text_len > 0) {
printf("TEXT(%.*s)\n", text_len, text_start);
}
}
action PrintTagNode {
int text_len = fpc - text_start - 1; /* drop closing bracket */
printf("TAG(%.*s)\n", text_len, text_start);
}
tag = '[[' (lower+ >MarkStart) ']]' @PrintTagNode;
main := (
(any - '[')* >MarkStart %PrintTextNode
('[' ^'[' %PrintTextNode | tag) >MarkStart
)* @eof(PrintTextNode);
}%%
몇 비 명백한 가지가 있습니다
- 가
eof
조치가 %PrintTextNode
때문에 필요는 기계를 떠날 때만 호출됩니다. 입력이 일반 텍스트로 끝나면 그 상태를 벗어나는 입력이 없습니다. 입력이 태그로 끝나고 마지막으로 인쇄되지 않은 텍스트 노드가 없을 때도 호출되기 때문에 PrintTextNode
은 인쇄 할 텍스트가 있는지 테스트합니다.
[
에 도달했을 때 시작이라고 표시했으나 [
이 아닌 값을 기록한 후에 다시 구문 분석을 시도하고 시작점을 말하기 시작하기 때문에 ^'['
이후에 동작이 필요합니다. %PrintTextNode
동작이 필요합니다. 우리는 그 두 가지 문자가 발생하기 전에 플러시 할 필요가 있습니다. 따라서 액션 호출입니다.
전체 구문 분석기가 이어집니다.여기
/* ragel so_tag.rl && gcc so_tag.c -o so_tag */
#include <stdio.h>
#include <string.h>
static char *text_start;
%%{
machine parser;
action MarkStart { text_start = fpc; }
action PrintTextNode {
int text_len = fpc - text_start;
if (text_len > 0) {
printf("TEXT(%.*s)\n", text_len, text_start);
}
}
action PrintTagNode {
int text_len = fpc - text_start - 1; /* drop closing bracket */
printf("TAG(%.*s)\n", text_len, text_start);
}
tag = '[[' (lower+ >MarkStart) ']]' @PrintTagNode;
main := (
(any - '[')* >MarkStart %PrintTextNode
('[' ^'[' %PrintTextNode | tag) >MarkStart
)* @eof(PrintTextNode);
}%%
%% write data;
int
main(void) {
char buffer[4096];
int cs;
char *p = NULL;
char *pe = NULL;
char *eof = NULL;
%% write init;
do {
size_t nread = fread(buffer, 1, sizeof(buffer), stdin);
p = buffer;
pe = p + nread;
if (nread < sizeof(buffer) && feof(stdin)) eof = pe;
%% write exec;
if (eof || cs == %%{ write error; }%%) break;
} while (1);
return 0;
}
몇 가지 테스트 입력입니다 :
[[header]]
<html>
<head><title>title</title></head>
<body>
<h1>[[headertext]]</h1>
<p>I am feeling very [[emotion]].</p>
<p>I like brackets: [ is cool. ] is cool. [] are cool. But [[tag]] is special.</p>
</body>
</html>
[[footer]]
그리고 여기에 출력의 그게 내가 무엇을 알고,하지만 당신은 아주 쉽게 필요한 어떤 언어 당신으로 바꿀 수 있어야하기 때문에 나는 C에서 그것을했다 구문 분석기에서 :
TAG(header)
TEXT(
<html>
<head><title>title</title></head>
<body>
<h1>)
TAG(headertext)
TEXT(</h1>
<p>I am feeling very)
TAG(emotion)
TEXT(.</p>
<p>I like brackets:)
TEXT([)
TEXT(is cool. ] is cool.)
TEXT([])
TEXT(are cool. But)
TAG(tag)
TEXT(is special.</p>
</body>
</html>
)
TAG(footer)
TEXT(
)
마지막 텍스트 노드에는 파일 끝의 개행 문자 만 포함됩니다.