В настоящее время я работаю над HTML-парсером / библиотекой шаблонов, используя Flex / Bison.У меня есть некоторые проблемы с моим заявлением if.Выражение хорошо разбирается (если вы> я), но когда дело доходит до утверждения между тегами начала и конца if, оно получает только первое слово и умирает в промежутке между ними.Просто интересно, как я могу гарантировать, что я получаю весь контент между тегами и не умираю в первом найденном месте.
Что я в основном делаю, так это перестраиваю файл с новыми значениями из переменных ({{var}}) и результаты операторов (например, {% if expression%} blah {% endif%}) (т. е. djangoish)
Вывод
you > me
If Statement:
if(you) {
Do
}
Пример шаблона
%{
#include <stdio.h>
#include "ink.tab.h"
using namespace std;
extern "C" {
int yyparse(void);
int yylex(void);
int yywrap();
}
extern void yyerror(char *err);
extern int LINENO;
const char *context;
%}
%%
/* Open/Close template tags */
"{{" { return OPENPRINT; }
"}}" { return CLOSEPRINT; }
"{%" { return OPENACTION; }
"%}" { return CLOSEACTION; }
/* Conditionals */
"!" { return BANG; }
"<" { return LT; }
">" { return GT; }
"==" { return EQ; }
"!=" { return NEQ; }
"<=" { return LTEQ; }
">=" { return GTEQ; }
"&&" { return ANDOP; }
"||" { return OROP; }
/* IF/ELSE handler */
"if" { return IF_TOKEN; }
"else" { return ELSE_TOKEN; }
"endif" { return ENDIF_TOKEN; }
/* FOR handler */
"for" { return FOR_TOKEN; }
"in" { return IN_TOKEN; }
"endfor" { return ENDFOR_TOKEN; }
/* Context grab */
[a-zA-Z0-9_]* { yylval.strval = strdup(yytext); return CONTEXT; }
/* Excuse the HTML tags */
\<[^>]*\> { context = strdup(yytext); fwrite(context, sizeof(char), strlen(context), yyout); }
/* Some catch alls */
[ \t]+ { context = strdup(yytext); fwrite(context, sizeof(char), strlen(context), yyout); }
\n { LINENO++; context = "\n"; fwrite(context, sizeof(char), strlen(context), yyout); }
. ;
%%
void yyerror(char *err)
{
printf("\nLine:\t%d\nError:\t%s\nText:\t%s\n", LINENO, err, yytext);
}
int yywrap()
{
return 1;
}
int main()
{
yyout = fopen("test.out", "w");
yyin = fopen("test.jhtml", "r");
yyparse();
}
Зубр
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <v8.h>
using namespace std;
using namespace v8;
extern "C" {
int yyparse(void);
int yylex(void);
int yywrap();
}
int LINENO = 1;
void yyerror(char *err);
extern FILE *yyout;
%}
%union {
int inval;
char *strval;
}
%token OPENPRINT
%token CLOSEPRINT
%token OPENACTION
%token CLOSEACTION
%token <strval> CONTEXT
%token IF_TOKEN
%token ELSE_TOKEN
%token ENDIF_TOKEN
%token FOR_TOKEN
%token IN_TOKEN
%token ENDFOR_TOKEN
%token TAGS
%token BANG
%token LT
%token GT
%token EQ
%token NEQ
%token LTEQ
%token GTEQ
%token ANDOP
%token OROP
%type <strval> context
%type <strval> expression
%type <strval> contexts
%%
commands:
command
|
commands command
;
command:
OPENPRINT echo CLOSEPRINT
|
expression
|
stmt
;
echo:
context {
char *context = $1;
fwrite(context, sizeof(char), strlen(context), yyout);
}
;
stmt:
OPENACTION IF_TOKEN expression CLOSEACTION contexts OPENACTION ENDIF_TOKEN CLOSEACTION {
printf("\nIf Statement: \n");
printf("if(%s) {\n\t%s\n}\n", $3, $5);
}
;
contexts:
context
|
contexts context
;
context:
CONTEXT { $$ = $1; }
;
expression:
context
|
context GT context { printf("\n%s > %s\n", $1, $3); }
|
context LT context {}
|
context EQ context {}
|
context NEQ context {}
|
context LTEQ context {}
|
context GTEQ context {}
|
context ANDOP context {}
|
context OROP context {}
|
BANG context {}
;
%%
Пример HTML-шаблона
{% if you > me %}
Do something here
{% endif %}