shithub: vcardfs

ref: 2f487c06c35d1a8b325f03fe640dd6e46d29b35f
dir: /libvcard/vcard.y/

View raw version
%{
#include <u.h>
#include <libc.h>
#include "vcard.h"

Vcard *vcparsecard;

extern int yylex(void);

void
yyerror(char *s)
{
	werrstr("%s (%10s)\n", s, vcstate.s);
}

static Vcard*
mkvcard(Vline *lines)
{
	Vcard *vc;
	vc = mallocz(sizeof(Vcard), 1);
	vc->content = lines;
	return vc;
}

static void
enqueue(Vcard *head, Vcard *tail)
{
	head->next = tail;
	vcparsecard = head;
}

static void
enqueuel(Vline *head, Vline *tail)
{
	head->next = tail;
}

static void
enqueuep(Vparam *head, Vparam *tail)
{
	head->next = tail;
}

static Vline*
mkline(char *name, Vparam *params, char *value, char *group)
{
	Vline *vl;
	vl = mallocz(sizeof(Vline), 1);
	vl->name = name;
	vl->value = value;
	vl->params = params;
	vl->group = group;
	/*
	fprint(2, "new line:\n");
	fprint(2, "  name: %s\n", name);
	fprint(2, "  value: %s\n", value);
	fprint(2, "  params: %p\n", params);
	fprint(2, "  group: %s\n", group);
	*/
	return vl;
}

static Vparam*
addparam(char *name, char *value)
{
	Vparam *vp;
	vp = mallocz(sizeof(Vparam), 1);
	vp->name = name;
	vp->value = value;
	return vp;
}

static char*
xname(char *s)
{
	char *n;
	n = smprint("x-%s", s);
	free(s);
	return n;
}

%}

%union {
	int i;
	Vcard *vc;
	Vline *vl;
	Vparam *vp;
	char *s;
}

%token	<i> 	BEGIN END CRLF

%token	<s> 	WORD SWORD FWORD
%token	<s> 	SOURCE KIND FN N NICKNAME PHOTO BDAY ANNIVERSARY GENDER
%token	<s> 	ADR TEL EMAIL IMPP LANG TZ GEO TITLE ROLE LOGO ORG MEMBER
%token	<s> 	RELATED CATEGORIES NOTE PRODID REV SOUND UID CLIENTPIDMAP
%token	<s> 	URL KEY FBURL CALADRURI CALURI XML

%type	<s> 	iana-token x-name
%type	<s> 	pvalue

%type	<vc>	vclist vcard
%type	<vl>	cline clinel
%type	<vp>	params param
%type	<s> 	group name value

%%

vclist:
	  vcard { $$ = $1; enqueue($1, nil); }
	| vcard vclist { $$ = $1; enqueue($1, $2); }
	;

vcard:
	  BEGIN clinel END { $$ = mkvcard($2); }
	| BEGIN clinel END CRLF { $$ = mkvcard($2); }
	;

clinel:
	  cline
	| cline clinel { $$ = $1; enqueuel($1, $2); }
	;

cline:
	  group '.' name params ':' value CRLF { $$ = mkline($3, $4, $6, $1); }
	| name params ':' value CRLF { $$ = mkline($1, $2, $4, nil); }
	| name ':' value CRLF { $$ = mkline($1, nil, $3, nil); }
	;

params:
	  ';' param { $$ = $2; }
	| ';' param params { $$ = $2; enqueuep($2, $3); }
	;

param: SWORD '=' pvalue { $$ = addparam($1, $3); };

pvalue:
	  SWORD
	| '"' WORD '"' { $$ = $2; }
	| '"' SWORD '"' { $$ = $2; }
	| '"' FWORD '"' { $$ = $2; }
	;

group: SWORD;
name:
	  SOURCE
	| KIND
	| FN
	| N
	| NICKNAME
	| PHOTO
	| BDAY
	| ANNIVERSARY
	| GENDER
	| ADR
	| TEL
	| EMAIL
	| IMPP
	| LANG
	| TZ
	| GEO
	| TITLE
	| ROLE
	| LOGO
	| ORG
	| MEMBER
	| RELATED
	| CATEGORIES
	| NOTE
	| PRODID
	| REV
	| SOUND
	| UID
	| CLIENTPIDMAP
	| URL
	| KEY
	| FBURL
	| CALADRURI
	| CALURI
	| XML
	| iana-token
	| x-name
	;

iana-token: SWORD;
x-name: 'x' '-' SWORD { $$ = xname($3); };

value: WORD | SWORD | FWORD;