==> Parsing a configuration file
สมมติจะ parse configuration ตัวนี้
zone "." {
type hint;
file "/etc/bind/db.root";
};
เริ่มต้นก็ต้องเขียน lex file ขึ้นมาก่อน return ให้ yacc เข้าพระทัยซะด้วย
%{
#include
#include "y.tab.h"
%}
%%
zone return ZONETOK;
file return FILETOK;
[a-zA-Z][a-zA-Z0-9]* yylval=strdup(yytext); return WORD;
[a-zA-Z0-9\/.-]+ yylval=strdup(yytext); return FILENAME;
\" return QUOTE;
\{ return OBRACE;
\} return EBRACE;
; return SEMICOLON;
\n /* ignore EOL */;
[ \t]+ /* ignore whitespace */;
%%
สังเกตว่า yylval จะไม่ใช่ integer แต่เป็น char * ดังนั้นก็เลยต้อง #define YYSTYPE char * ให้ yacc รู้จักก่อน
ตอนเริ่มเขียน yacc grammer นี้ชักจะเริ่มมั่วนิดส์นึง
เริ่มการ recusive ที่ root
commands:
|
commands command SEMICOLON
;
คือว่าแต่ละ command แยกกันด้วย ";"(semicolon)
command:
zone_set
;
zone_set:
ZONETOK quotedname zonecontent
{
printf("Complete zone for '%s' found\n",$2);
}
;
มี zonecontent ด้วย
zonecontent:
OBRACE zonestatements EBRACE
จะต้องมี { OBRACE และ } EBRACE
quotedname:
QUOTE FILENAME QUOTE
{
$$=$2;
}
นั่นคือ quotedname เท่ากับ filename
NOTE: this grammar chokes on filenames without either a '.' or a '/' in them.
zonestatements:
|
zonestatements zonestatement SEMICOLON
;
zonestatement:
statements
|
FILETOK quotedname
{
printf("A zonefile name '%s' was encountered\n", $2);
}
;
This is a generic statement that catches all kinds of statements within the 'zone' block. We again see the recursiveness.
block:
OBRACE zonestatements EBRACE SEMICOLON
;
statements:
| statements statement
;
statement: WORD | block | quotedname
ไม่มีความคิดเห็น:
แสดงความคิดเห็น