Created
August 9, 2012 09:23
-
-
Save jaytaph/3302630 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%{ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include "node.h" | |
#include "parser.tab.h" | |
%} | |
%option yylineno | |
lnum [0-9]+ | |
identifier [\$a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*[\?\!]? | |
whitespace [ \t\n\r]+ | |
sl_comment "//".+ | |
ml_comment "/*"([^\*]|\*[^/])*"*/" | |
opening_tags [\"\'] | |
closing_tags [\"\'] | |
%% | |
{ml_comment}|{sl_comment} { } | |
{whitespace} { } | |
[-+<>\(\)\{\}:;=,\.\[\]\?!\*^] { return yytext[0]; } | |
">=" return T_GE; | |
"<=" return T_LE; | |
"==" return T_EQ; | |
"!=" return T_NE; | |
"in" return T_IN; | |
"||" return T_OR; | |
"&&" return T_AND; | |
"<<" return T_SHIFT_LEFT; | |
">>" return T_SHIFT_RIGHT; | |
"+=" return T_PLUS_ASSIGNMENT; | |
"-=" return T_MINUS_ASSIGNMENT; | |
"*=" return T_MUL_ASSIGNMENT; | |
"/=" return T_DIV_ASSIGNMENT; | |
"%=" return T_MOD_ASSIGNMENT; | |
"&=" return T_AND_ASSIGNMENT; | |
"|=" return T_OR_ASSIGNMENT; | |
"^=" return T_XOR_ASSIGNMENT; | |
"<<=" return T_SL_ASSIGNMENT; | |
">>=" return T_SR_ASSIGNMENT; | |
"while" return T_WHILE; | |
"if" return T_IF; | |
"else" return T_ELSE; | |
"use" return T_USE; | |
"as" return T_AS; | |
"do" return T_DO; | |
"for" return T_FOR; | |
"switch" return T_SWITCH; | |
"class" return T_CLASS; | |
"extends" return T_EXTENDS; | |
"implements" return T_IMPLEMENTS; | |
"abstract" return T_ABSTRACT; | |
"final" return T_FINAL; | |
"interface" return T_INTERFACE; | |
"const" return T_CONST; | |
"static" return T_STATIC; | |
"public" return T_PUBLIC; | |
"private" return T_PRIVATE; | |
"protected" return T_PROTECTED; | |
"method" return T_METHOD; | |
"readonly" return T_READONLY; | |
"property" return T_PROPERTY; | |
"catch" return T_CATCH; | |
"finally" return T_FINALLY; | |
"throw" return T_THROW; | |
"return" return T_RETURN; | |
"break" return T_BREAK; | |
"breakelse" return T_BREAKELSE; | |
"continue" return T_CONTINUE; | |
"try" return T_TRY; | |
"default" return T_DEFAULT; | |
"goto" return T_GOTO; | |
"self" return T_SELF; | |
"parent" return T_PARENT; | |
{opening_tags}[^\"]*{closing_tags} { | |
yylval.sVal = strdup(yytext+1); | |
if (yylval.sVal[yyleng-2] != yytext[0]) { | |
fprintf(stderr,"improperly terminated string"); | |
} else { | |
yylval.sVal[yyleng-2] = 0; | |
} | |
return T_STRING; } | |
{identifier} { | |
yylval.sVal = strdup(yytext); | |
return T_IDENTIFIER; | |
} | |
{lnum} { | |
yylval.lVal = strtol(yytext, NULL, 10); | |
return T_LNUM; } | |
. { | |
printf ("Unknown token: '%s'\n", yytext); | |
yyterminate(); | |
} | |
%% | |
int yywrap(void) { return 1; } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%{ | |
#include <stdio.h> | |
#include "node.h" | |
#include "saffire_parser.h" | |
extern int yylineno; | |
int yylex(void); | |
void yyerror(const char *err) { printf("Error in line: %d: %s\n", yylineno, err); } | |
#ifdef __DEBUG | |
#define YYDEBUG 1 | |
#define TRACE(p) printf("Reduce at line %d: %s\n", __LINE__, p); | |
#else | |
#define YYDEBUG 0 | |
#define TRACE(p) | |
#endif | |
%} | |
%union { | |
char *sVal; | |
long lVal; | |
double dVal; | |
nodeType *nPtr; | |
} | |
%token END 0 "end of file" | |
%token <lVal> T_LNUM | |
%token <sVal> T_STRING | |
%token <sVal> T_IDENTIFIER | |
%token T_WHILE T_IF T_USE T_AS T_DO T_SWITCH T_FOR | |
%nonassoc T_ELSE | |
%token T_PLUS_ASSIGNMENT | |
%token T_MINUS_ASSIGNMENT | |
%token T_MUL_ASSIGNMENT | |
%token T_DIV_ASSIGNMENT | |
%token T_MOD_ASSIGNMENT | |
%token T_AND_ASSIGNMENT | |
%token T_OR_ASSIGNMENT | |
%token T_XOR_ASSIGNMENT | |
%token T_SL_ASSIGNMENT | |
%token T_SR_ASSIGNMENT | |
%token T_CATCH T_BREAK T_GOTO T_BREAKELSE T_CONTINUE T_THROW T_RETURN T_FINALLY T_TRY T_DEFAULT T_METHOD | |
%token T_SELF T_PARENT | |
%left '=' T_GE T_LE T_EQ T_NE '>' '<' '^' T_IN | |
%left '+' '-' | |
%left '*' '/' | |
%token T_AND T_OR T_SHIFT_LEFT T_SHIFT_RIGHT | |
/* | |
%token use_statement interface_method_definition method_argument_list | |
%token class_inner_statements top_statement_list top_statement | |
%token class_definition interface_definition constant_list constant | |
%token scalar_value interface_inner_statements real_scalar_value | |
%token class_method_definition statement_list statement | |
%token calling_method_argument_list interface_property_definition | |
%token jump_statement iteration_statement guarding_statement class_property_definition | |
%token expression_statement label_statement selection_statement compound_statement expression | |
%token assignment_expression assignment_operator unary_expression catch_list catch_header catch | |
%token list_element_list hash_element_list hash_scalar_indexes | |
*/ | |
%token T_CLASS T_EXTENDS T_ABSTRACT T_FINAL T_IMPLEMENTS T_INTERFACE | |
%token T_PUBLIC T_PRIVATE T_PROTECTED T_CONST T_STATIC T_READONLY T_PROPERTY | |
%start saffire | |
%% /* rules */ | |
/** | |
************************************************************ | |
* TOP AND USE STATEMENTS | |
************************************************************ | |
*/ | |
saffire: | |
/* Use statements are only possible at the top of a file */ | |
use_statement_list { TRACE("use_statement_list") } | |
/* Top statements follow use statements */ | |
top_statement_list { TRACE("top_statement_list") } | |
; | |
use_statement_list: | |
non_empty_use_statement_list { TRACE("use_staement_list") } | |
| /* empty */ { TRACE("empty statementlist") } | |
; | |
non_empty_use_statement_list: | |
use_statement { TRACE("") } | |
| non_empty_use_statement_list use_statement { TRACE("") } | |
; | |
use_statement: | |
/* use <foo> as <bar>; */ | |
T_USE T_IDENTIFIER T_AS T_IDENTIFIER ';' { TRACE("") } | |
/* use <foo>; */ | |
| T_USE T_IDENTIFIER ';' { TRACE("") } | |
; | |
/* Top statements are single (global) statements and/or class/interface/constant */ | |
top_statement_list: | |
non_empty_top_statement_list { TRACE("ne top statement list") } | |
| /* empty */ { } | |
; | |
non_empty_top_statement_list: | |
top_statement{ TRACE("top statement") } | |
| non_empty_top_statement_list top_statement { TRACE("top statement next") } | |
; | |
/* Top statements can be classes, interfaces, constants, statements */ | |
top_statement: | |
class_definition { TRACE("class definition") } | |
| interface_definition { TRACE("interface definition") } | |
| constant_list { TRACE("constant list") } | |
| statement_list { TRACE("statement list") } | |
; | |
/** | |
************************************************************ | |
* BLOCKS & STATEMENTS | |
************************************************************ | |
*/ | |
/* A compound statement is a (set of) statement captured by curly brackets */ | |
compound_statement: | |
'{' '}' { TRACE("empty compound") } | |
| '{' { TRACE("compound statement start") } statement_list '}' { TRACE("compound statement end") } | |
; | |
statement_list: | |
statement { TRACE("statement") } | |
| statement_list statement { TRACE("statement element") } | |
; | |
statement: | |
label_statement { TRACE("label_statement") } | |
| compound_statement { TRACE("compound_statement") } | |
| expression_statement { TRACE("expression_statement") } | |
| selection_statement { TRACE("selection_statement") } | |
| iteration_statement { TRACE("iteration_statement") } | |
| jump_statement { TRACE("jump_statement") } | |
| guarding_statement { TRACE("guarding_statement") } | |
; | |
selection_statement: | |
T_IF expression statement { TRACE("endif") } | |
| T_IF expression statement T_ELSE statement { TRACE("endif-else") } | |
| T_SWITCH expression statement { TRACE("") } | |
; | |
iteration_statement: | |
T_WHILE expression statement T_ELSE statement { TRACE("endwhile-else") } | |
| T_WHILE expression statement { TRACE("endwhile") } | |
| T_DO statement T_WHILE expression ';' { TRACE("") } | |
| T_FOR '(' expression_statement expression_statement ')' statement { TRACE("") } | |
| T_FOR '(' expression_statement expression_statement expression ')' statement { TRACE("") } | |
/* | foreach() { } */ | |
; | |
expression_statement: | |
';' { TRACE("empty expression") } | |
| expression ';' { TRACE("expression") } | |
; | |
jump_statement: | |
T_BREAK ';' { TRACE("") } | |
| T_BREAKELSE ';' { TRACE("") } | |
| T_CONTINUE ';' { TRACE("") } | |
| T_RETURN ';' { TRACE("") } | |
| T_RETURN expression ';' { TRACE("") } | |
| T_THROW expression ';' { TRACE("") } | |
| T_GOTO T_IDENTIFIER ';' { TRACE("") } | |
; | |
guarding_statement: | |
T_TRY compound_statement catch_list { TRACE("") } | |
| T_TRY compound_statement catch_list T_FINALLY compound_statement { TRACE("") } | |
| T_TRY compound_statement T_FINALLY compound_statement { TRACE("") } | |
; | |
catch_list: | |
catch { TRACE("") } | |
| catch_list catch { TRACE("") } | |
; | |
catch: | |
catch_header compound_statement { TRACE("") } | |
; | |
catch_header: | |
T_CATCH '(' T_IDENTIFIER T_IDENTIFIER ')' { TRACE("") } | |
| T_CATCH '(' T_IDENTIFIER ')' { TRACE("") } | |
| T_CATCH '(' ')' { TRACE("") } | |
; | |
label_statement: | |
T_IDENTIFIER ':' { TRACE("") } | |
/* | T_CASE ConstantExpression ':' */ | |
| T_DEFAULT ':' { TRACE("") } | |
; | |
/** | |
************************************************************ | |
* ASSIGNMENT & EXPRESSION | |
************************************************************ | |
*/ | |
expression: | |
assignment_expression { TRACE("expr") } | |
| expression ',' assignment_expression { TRACE("expr ,") } | |
; | |
assignment_expression: | |
conditional_expression { TRACE("assignment expr") } | |
| unary_expression assignment_operator assignment_expression { TRACE("assignment expr, ") } | |
; | |
conditional_expression: | |
conditional_or_expression { TRACE("cond expr") } | |
| conditional_or_expression '?' expression ':' conditional_expression { TRACE("cond expr") } | |
; | |
conditional_or_expression: | |
conditional_and_expression { TRACE("cond or expr") } | |
| conditional_or_expression T_OR conditional_and_expression { TRACE("cond OR") } | |
; | |
conditional_and_expression: | |
inclusive_or_expression { TRACE("cond and epr") } | |
| conditional_and_expression T_AND inclusive_or_expression { TRACE("cond AND") } | |
; | |
inclusive_or_expression: | |
exclusive_or_expression { TRACE("incl or expr") } | |
| inclusive_or_expression '|' exclusive_or_expression { TRACE("incl OR") } | |
; | |
exclusive_or_expression: | |
and_expression { TRACE("excl or expr") } | |
| exclusive_or_expression '^' and_expression { TRACE("excl OR") } | |
; | |
and_expression: | |
equality_expression { TRACE("and expr") } | |
| and_expression '&' equality_expression { TRACE("AND") } | |
; | |
equality_expression: | |
relational_expression { TRACE("equal expr") } | |
| equality_expression T_EQ relational_expression { TRACE("eq") } | |
| equality_expression T_NE relational_expression { TRACE("ne") } | |
| equality_expression T_IN relational_expression { TRACE("in") } | |
; | |
relational_expression: | |
shift_expression { TRACE("relat expr") } | |
| relational_expression '>' shift_expression { TRACE("") } | |
| relational_expression '<' shift_expression { TRACE("") } | |
| relational_expression T_LE shift_expression { TRACE("") } | |
| relational_expression T_GE shift_expression { TRACE("") } | |
; | |
shift_expression: | |
additive_expression { TRACE("shift expr") } | |
| shift_expression T_SHIFT_LEFT additive_expression { TRACE("") } | |
| shift_expression T_SHIFT_RIGHT additive_expression { TRACE("") } | |
; | |
additive_expression: | |
multiplicative_expression { TRACE("add expr") } | |
| additive_expression '+' multiplicative_expression { TRACE("") } | |
| additive_expression '-' multiplicative_expression { TRACE("") } | |
; | |
multiplicative_expression: | |
unary_expression { TRACE("multi expr") } | |
| multiplicative_expression '*' unary_expression { TRACE("me *") } | |
| multiplicative_expression '/' unary_expression { TRACE("me /") } | |
| multiplicative_expression '%' unary_expression { TRACE("me %") } | |
; | |
unary_expression: | |
arithmic_unary_operator primary_expression { TRACE("unary expr") } | |
| logical_unary_expression | |
; | |
logical_unary_expression: | |
primary_expression | |
| logical_unary_operator unary_expression | |
; | |
primary_expression: | |
qualified_name { TRACE("prim QF") } | |
| not_just_name { TRACE("notjustname") } | |
; | |
arithmic_unary_operator: | |
'+' { TRACE("+") } | |
| '-' { TRACE("-") } | |
; | |
logical_unary_operator: | |
'~' { TRACE("~") } | |
| '!' { TRACE("!") } | |
; | |
/* Things that can be used as assignment '=', '+=' etc.. */ | |
assignment_operator: | |
'=' { TRACE("=") } | |
| T_PLUS_ASSIGNMENT { TRACE("+") } | |
| T_MINUS_ASSIGNMENT { TRACE("-") } | |
| T_MUL_ASSIGNMENT { TRACE("") } | |
| T_DIV_ASSIGNMENT { TRACE("") } | |
| T_MOD_ASSIGNMENT { TRACE("") } | |
| T_AND_ASSIGNMENT { TRACE("") } | |
| T_OR_ASSIGNMENT { TRACE("") } | |
| T_XOR_ASSIGNMENT { TRACE("") } | |
| T_SL_ASSIGNMENT { TRACE("") } | |
| T_SR_ASSIGNMENT { TRACE("") } | |
; | |
real_scalar_value: | |
T_LNUM { TRACE("") } | |
| T_STRING { TRACE("") } | |
; | |
qualified_name: | |
T_IDENTIFIER | |
| qualified_name '.' T_IDENTIFIER { TRACE("QF") } | |
; | |
calling_method_argument_list: | |
expression { TRACE("") } | |
| calling_method_argument_list ',' expression { TRACE("") } | |
| /* empty */ { TRACE("") } | |
; | |
not_just_name: | |
special_name { TRACE("") } | |
| complex_primary { TRACE("") } | |
; | |
complex_primary: | |
'(' expression ')' { TRACE("") } | |
| complex_primary_no_parenthesis { TRACE("") } | |
; | |
complex_primary_no_parenthesis: | |
T_LNUM { TRACE("num") } | |
| T_STRING { TRACE("string") } | |
| array_access { TRACE("array xs") } | |
| field_access { TRACE("field xs") } | |
| method_call { TRACE("methodcall") } | |
; | |
array_access: | |
qualified_name '[' expression ']' { TRACE("") } | |
| complex_primary '[' expression ']' { TRACE("") } | |
; | |
field_access: | |
not_just_name '.' T_IDENTIFIER | |
| primary_expression '.' T_IDENTIFIER | |
; | |
method_call: | |
method_access '(' calling_method_argument_list ')' { TRACE("") } | |
| method_access '(' ')' { TRACE("") } | |
; | |
method_access: | |
complex_primary_no_parenthesis { TRACE("") } | |
| special_name { TRACE("") } | |
| qualified_name { TRACE("") } | |
; | |
special_name: | |
T_SELF { TRACE("self") } | |
| T_PARENT { TRACE("parent") } | |
; | |
/** | |
************************************************************ | |
* CLASS PARSING | |
************************************************************ | |
*/ | |
/* Statements inside a class: constant and methods */ | |
class_inner_statement_list: | |
class_inner_statement { TRACE("is_constant") } | |
| class_inner_statement_list class_inner_statement { TRACE("is_constant_l") } | |
; | |
class_inner_statement: | |
constant { TRACE("is_constant") } | |
| class_property_definition { TRACE("is_prop") } | |
| class_method_definition { TRACE("is_meth") } | |
; | |
/* Statements inside an interface: constant and methods */ | |
interface_inner_statement_list: | |
interface_inner_statement { TRACE("") } | |
| interface_inner_statement_list interface_inner_statement { TRACE("") } | |
; | |
interface_inner_statement: | |
interface_method_definition | |
| interface_property_definition | |
; | |
interface_method_definition: | |
modifier_list T_METHOD T_IDENTIFIER '(' method_argument_list ')' ';' { TRACE("") } | |
| T_METHOD T_IDENTIFIER '(' method_argument_list ')' ';' { TRACE("") } | |
; | |
class_method_definition: | |
modifier_list T_METHOD T_IDENTIFIER '(' method_argument_list ')' { TRACE("Method def") } compound_statement { TRACE("") } | |
| T_METHOD T_IDENTIFIER '(' method_argument_list ')' { TRACE("Method def") } compound_statement { TRACE("") } | |
| interface_method_definition | |
; | |
method_argument_list: | |
/* empty */ | |
| non_empty_method_argument_list | |
; | |
non_empty_method_argument_list: | |
expression { TRACE("") } | |
| non_empty_method_argument_list ',' expression { TRACE("") } | |
; | |
constant_list: | |
constant { TRACE("") } | |
| constant_list constant { TRACE("") } | |
; | |
constant: | |
T_CONST T_IDENTIFIER '=' real_scalar_value ';' { TRACE("") } | |
; | |
class_definition: | |
modifier_list T_CLASS T_IDENTIFIER class_extends class_interface_implements | |
'{' | |
class_inner_statement_list | |
'}' { TRACE("") } | |
| modifier_list T_CLASS T_IDENTIFIER class_extends class_interface_implements '{' '}' { TRACE("") } | |
| T_CLASS T_IDENTIFIER class_extends class_interface_implements '{' '}' { TRACE("") } | |
; | |
interface_definition: | |
T_INTERFACE T_IDENTIFIER class_interface_implements | |
'{' | |
interface_inner_statement_list | |
'}' { TRACE("") } | |
| /* empty interface */ | |
T_INTERFACE T_IDENTIFIER class_interface_implements '{' '}' { TRACE("") } | |
; | |
class_property_definition: | |
modifier_list T_PROPERTY T_IDENTIFIER '=' complex_primary_no_parenthesis ';' { TRACE("") } | |
| modifier_list T_PROPERTY T_IDENTIFIER ';' { TRACE("") } | |
; | |
interface_property_definition: | |
modifier_list T_PROPERTY T_IDENTIFIER ';' { TRACE("") } | |
; | |
/* Modifier list can be either empty, or filled */ | |
modifier_list: | |
non_empty_modifier_list { TRACE("modified_list") } | |
; | |
/* Has at least one modifier */ | |
non_empty_modifier_list: | |
modifier { TRACE("modified") } | |
| non_empty_modifier_list modifier { TRACE("ne_modifier_list") } | |
; | |
/* Property and method modifiers. */ | |
modifier: | |
T_PROTECTED { TRACE("protected") } | |
| T_PUBLIC { TRACE("public") } | |
| T_PRIVATE { TRACE("private") } | |
| T_FINAL { TRACE("final") } | |
| T_ABSTRACT { TRACE("abstract") } | |
| T_STATIC { TRACE("static") } | |
| T_READONLY { TRACE("readonly") } | |
; | |
/* extends a list of classes, or no extends at all */ | |
class_extends: | |
T_EXTENDS class_list { TRACE("") } | |
| /* empty */ | |
; | |
/* implements a list of classes, or no implement at all */ | |
class_interface_implements: | |
T_IMPLEMENTS class_list { TRACE("") } | |
| /* empty */ | |
; | |
/* Comma separated list of classes (for extends and implements) */ | |
class_list: | |
class_list ',' T_IDENTIFIER { TRACE("") } | |
| T_IDENTIFIER { TRACE("") } | |
; | |
/** | |
************************************************************ | |
* | |
************************************************************ | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment