📄 css_syntax.y
字号:
%{#include <stdio.h>#include <string.h>#include "css_lex.h"#include "parser.h"#define YYPARSE_PARAM yyparam#define YYERROR_VERBOSE 1//#define YYDEBUG 1%}%pure_parser%union { char *lexeme; char letter; struct property_t *property; struct selector_t *selector; struct selector_list_t *selector_list; int pseudo_class; int pseudo_element;}%token IMPORT_SYM%token IMPORTANT_SYM%token IDENT%token STRING%token NUMBER%token PERCENTAGE%token LENGTH%token EMS%token EXS%token LINK_PSCLASS_AFTER_IDENT%token VISITED_PSCLASS_AFTER_IDENT%token ACTIVE_PSCLASS_AFTER_IDENT%token FIRST_LINE_AFTER_IDENT%token FIRST_LETTER_AFTER_IDENT%token HASH_AFTER_IDENT%token CLASS_AFTER_IDENT%token LINK_PSCLASS%token VISITED_PSCLASS%token ACTIVE_PSCLASS%token FIRST_LINE%token FIRST_LETTER%token HASH%token CLASS%token URL%token RGB%token CDO%token CDC%token CSL%type <pseudo_class> solitary_pseudo_class%type <pseudo_class> pseudo_class%type <selector> selector%type <selector> simple_selector%type <selector> simple_selectors%type <selector_list> selectors%type <selector_list> ruleset%type <selector_list> rulesets%type <pseudo_element> pseudo_element%type <selector> solitary_pseudo_element%type <letter> unary_operator%type <letter> operator%type <property> declaration%type <property> declarations%type <lexeme> NUMBER%type <lexeme> STRING%type <lexeme> PERCENTAGE%type <lexeme> LENGTH%type <lexeme> EMS%type <lexeme> EXS%type <lexeme> URL%type <lexeme> RGB%type <lexeme> IDENT%type <lexeme> HASH%type <lexeme> HASH_AFTER_IDENT%type <lexeme> CLASS_AFTER_IDENT%type <lexeme> CLASS%type <lexeme> hexcolor%type <lexeme> value%type <lexeme> id%type <lexeme> solitary_id%type <lexeme> term%type <lexeme> property%type <lexeme> expr%type <lexeme> element_name%type <lexeme> class%type <lexeme> solitary_class%type <lexeme> string_or_url%%stylesheet: comments imports rulesets { *(struct selector_list_t**) yyparam = $3; };rulesets: ruleset comments rulesets { struct selector_list_t *pos = $1; if (pos != NULL) { while (pos->next != NULL) { pos = pos->next; } pos->next = $3; } else { $1 = $3; } $$ = $1; }| { $$ = NULL; };imports: import comments imports|;comments: comments comment|;comment: CDO| CDC| CSL;import: IMPORT_SYM string_or_url ';' /* E.g., @import url(fun.css); */;string_or_url: STRING { $$ = $1; }| URL { char *begin = $1; char *end = $1 + strlen($1); /* Skip url( */ begin += 4; /* skip whitespace */ while (*begin == ' ') ++begin; /* Skip ) */ end -= 2; /* skip whitespace */ while (*end == ' ') --end; end[1] = 0; $$ = strdup(begin); free($1); };unary_operator: '-' { $$ = '-'; }| '+' { $$ = '+'; };operator: '/' { $$ = '/'; }| ',' { $$ = ','; }| /* empty */ {$$ = ' '; };property: IDENT { $$ = $1; };ruleset: selectors '{' declarations '}' { struct selector_list_t *pos = $1; while (pos != NULL) { struct property_t *i = $3; while (i != NULL) { i->count++; i = i->next; } pos->selector->property = $3; pos = pos->next; } $$ = $1; };selectors: selector { if ($1 != NULL) { $$ = (struct selector_list_t*) malloc (sizeof(struct selector_list_t)); $$->selector = $1; $$->next = NULL; } else { $$ = NULL; } }| selector ',' selectors { if ($1 != NULL) { struct selector_list_t *new; new = (struct selector_list_t*) malloc (sizeof(struct selector_list_t)); new->selector = $1; new->next = $3; $$ = new; } else { $$ = $3; } };declarations: declaration { $$ = $1; }| declaration ';' declarations { if ($1 != NULL) { $1->next = $3; $$ = $1; } else { $$ = $3; } };selector: simple_selectors pseudo_element { struct selector_t *pos = $1; while (pos->next != NULL) { pos = pos->next; } pos->pseudo_element = $2; $$ = $1; }| simple_selectors solitary_pseudo_element { struct selector_t *pos = $1; while (pos->next != NULL) { pos = pos->next; } pos->next = $2; $$ = $1; }| simple_selectors { $$ = $1; }| solitary_pseudo_element { $$ = $1; }| selector error { $$ = NULL; }| error { $$ = NULL; };simple_selectors: simple_selector { $$ = $1; }| simple_selector simple_selectors { $1->next = $2; $$ = $1; };/* An "id" is an ID that is attached to an element type ** on its left, as in: P#p007 ** A "solitary_id" is an ID that is not so attached, ** as in: #p007 ** Analogously for classes and pseudo-classes. */simple_selector: element_name id class pseudo_class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = $1; $$->id = $2; $$->e_class = $3; $$->pseudo_class = $4; $$->pseudo_element = 0; $$->next = NULL; } /* eg: H1.subject */| element_name id pseudo_class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = $1; $$->id = $2; $$->e_class = NULL; $$->pseudo_class = $3; $$->pseudo_element = 0; $$->next = NULL; }| element_name class pseudo_class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = $1; $$->id = NULL; $$->e_class = $2; $$->pseudo_class = $3; $$->pseudo_element = 0; $$->next = NULL; }| element_name id class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = $1; $$->id = $2; $$->e_class = $3; $$->pseudo_class = 0; $$->pseudo_element = 0; $$->next = NULL; }| element_name id { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = $1; $$->id = $2; $$->e_class = NULL; $$->pseudo_class = 0; $$->pseudo_element = 0; $$->next = NULL; }| element_name class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = $1; $$->id = NULL; $$->e_class = $2; $$->pseudo_class = 0; $$->pseudo_element = 0; $$->next = NULL; }| element_name pseudo_class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = $1; $$->id = NULL; $$->e_class = NULL; $$->pseudo_class = $2; $$->pseudo_element = 0; $$->next = NULL; }| element_name { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = $1; $$->id = NULL; $$->e_class = NULL; $$->pseudo_class = 0; $$->pseudo_element = 0; $$->next = NULL; }| solitary_id class pseudo_class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = NULL; $$->id = $1; $$->e_class = $2; $$->pseudo_class = $3; $$->pseudo_element = 0; $$->next = NULL; } /* eg: #xyz33 */| solitary_id class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = NULL; $$->id = $1; $$->e_class = $2; $$->pseudo_class = 0; $$->pseudo_element = 0; $$->next = NULL; }| solitary_id pseudo_class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = NULL; $$->id = $1; $$->e_class = NULL; $$->pseudo_class = $2; $$->pseudo_element = 0; $$->next = NULL; }| solitary_id { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = NULL; $$->id = $1; $$->e_class = NULL; $$->pseudo_class = 0; $$->pseudo_element = 0; $$->next = NULL; }| solitary_class pseudo_class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = NULL; $$->id = NULL; $$->e_class = $1; $$->pseudo_class = $2; $$->pseudo_element = 0; $$->next = NULL; }/* eg: .author */| solitary_class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = NULL; $$->id = NULL; $$->e_class = $1; $$->pseudo_class = 0; $$->pseudo_element = 0; $$->next = NULL; }| solitary_pseudo_class { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = NULL; $$->id = NULL; $$->e_class = NULL; $$->pseudo_class = $1; $$->pseudo_element = 0; $$->next = NULL; } /* eg: :link */;element_name: IDENT { $$ = $1; };pseudo_class /* as in: A:link */: LINK_PSCLASS_AFTER_IDENT { $$ = PS_CLASS_LINK; }| VISITED_PSCLASS_AFTER_IDENT { $$ = PS_CLASS_VISITED; }| ACTIVE_PSCLASS_AFTER_IDENT { $$ = PS_CLASS_ACTIVE; };solitary_pseudo_class /* as in: :link */: LINK_PSCLASS { $$ = PS_CLASS_LINK; }| VISITED_PSCLASS { $$ = PS_CLASS_VISITED; }| ACTIVE_PSCLASS { $$ = PS_CLASS_ACTIVE; };class /* as in: P.note */: CLASS_AFTER_IDENT { $$ = $1; };solitary_class /* as in: .note */: CLASS { $$ = $1; };pseudo_element /* as in: P:first-line */: FIRST_LETTER_AFTER_IDENT { $$ = PS_ELEMENT_FIRST_LETTER; }| FIRST_LINE_AFTER_IDENT { $$ = PS_ELEMENT_FIRST_LINE; };solitary_pseudo_element /* as in: :first-line */: FIRST_LETTER { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = NULL; $$->id = NULL; $$->e_class = NULL; $$->pseudo_class = 0; $$->pseudo_element = PS_ELEMENT_FIRST_LETTER; $$->next = NULL; }| FIRST_LINE { $$ = (struct selector_t*) malloc(sizeof(struct selector_t)); $$->element_name = NULL; $$->id = NULL; $$->e_class = NULL; $$->pseudo_class = 0; $$->pseudo_element = PS_ELEMENT_FIRST_LINE; $$->next = NULL; };/* There is a constraint on the id and solitary_id that the ** part after the "#" must be a valid HTML ID value; ** e.g., "#x77" is OK, but "#77" is not. */id: HASH_AFTER_IDENT { $$ = $1; };solitary_id: HASH { $$ = $1; };declaration: property ':' expr prio { $$ = (struct property_t*) malloc(sizeof(struct property_t)); $$->name = $1; $$->val = $3; $$->important = 1; $$->count = 0; $$->next = NULL; }| property ':' expr { $$ = (struct property_t*) malloc(sizeof(struct property_t)); $$->name = $1; $$->val = $3; $$->important = 0; $$->count = 0; $$->next = NULL; }| error { $$ = NULL; }| /* empty */ { $$ = NULL; } /* Prevents syntax errors... */;prio: IMPORTANT_SYM { } /* !important */;expr: term { $$ = $1; } | expr operator term { char *s = (char*) malloc (strlen($1)+strlen($3)+2); strcpy(s, $1); s[strlen(s)+1] = 0; s[strlen(s)] = $2; strcat(s, $3); free($1); free($3); $$ = s; }| expr error { $$ = $1; };term: unary_operator value { char *s = (char*) malloc(strlen($2)+2); s[0] = $1; s[1] = 0; strcat(s, $2); free($2); $$ = s; }| value { $$ = $1; };value: NUMBER { $$ = $1; }| STRING { $$ = $1; }| PERCENTAGE { $$ = $1; }| LENGTH { $$ = $1; }| EMS { $$ = $1; }| EXS { $$ = $1; }| IDENT { $$ = $1; }| hexcolor { $$ = $1; }| URL { $$ = $1; }| RGB { $$ = $1; }; /* There is a constraint on the color that it must ** have either 3 or 6 hex-digits (i.e., [0-9a-fA-F]) ** after the "#"; e.g., "#000" is OK, but "#abcd" is not. */hexcolor: HASH { $$ = (char*) malloc (strlen($1)+2); sprintf($$, "#%s", $1); free($1); }| HASH_AFTER_IDENT { $$ = (char*) malloc (strlen($1)+2); sprintf($$, "#%s", $1); free($1); };%%int yyerror(char *s) {#if YYDEBUG fprintf(stderr, "Error: %s\n", s);#endif return 0;}struct selector_list_t* css_parse(const char *buffer, int buf_len) { struct selector_list_t *ret = NULL; //yydebug = 1; init_yylex(buffer, buf_len); yyparse(&ret); end_yylex(); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -