Skip to content

Instantly share code, notes, and snippets.

@tj
Created August 10, 2009 21:24
Show Gist options
  • Save tj/165428 to your computer and use it in GitHub Desktop.
Save tj/165428 to your computer and use it in GitHub Desktop.
%{
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#define YYSTYPE char *
#define LLP_VERSION "0.0.1"
#define DUP yy = strdup(yytext);
#define LPAREN '{'
#define RPAREN '}'
#define VAR sprintf(buf, "$%s", yytext); yy = strdup(buf);
static char buf[1024];
static int in_array = 0;
%}
Main = Comment
| '<?llp' { printf("<?php \n ") }
| Define
| Method
| Subclass
| v:Constant { printf(v) }
| Cast
| Native
| Function
| Range
| Unless
| Case
| ArrayPair
| Array
| Accessor
| Each
| v:Keyword { printf(v) }
| 'require' s v:Id { printf("require('%s.php')", v) }
| 'require' s v:String { printf("require(%s)", v) }
| ':' v:Id '(' { printf("$%s(", v) }
| v:Id '(' { printf("%s(", v) }
| 'p' s v:Literal { printf("__inspect__(%s)", v) }
| v:Literal { printf(v) }
| < . > { printf(yytext) }
Range = a:Int '..' b:Int { printf("range(%s, %s)", a, b) }
| a:Char '..' b:Char { printf("range(%s, %s)", a, b) }
Subclass = a:Constant - '<' - b:Constant { printf("%s extends %s", a, b) }
Native = 'native' s v:Id s 'as' s a:Id s b:Id { printf("function __%s_%s(&$self) {\n $args = func_get_args(); return call_user_func_array('%s', $args); \n}", a, b, v) }
| 'native' s v:Id s 'as' s a:Id { printf("function __%s(&$self) {\n $args = func_get_args(); return call_user_func_array('%s', $args); \n}", a, v) }
Consume = < (!';' .)+ > ';' { DUP }
Case = 'case' s v:Literal - Newline
(- '|' - a:Literal - ':' c:Consume Newline)
{ printf("if (__send__('equal', %s, %s)){\n %s; \n} ", v, a, c) }
(- '|' - a:Literal - ':' c:Consume Newline)*
{ printf("elseif (__send__('equal', %s, %s)){\n %s; \n} ", v, a, c) }
(- '|' - c:Consume EOL)
{ printf("else {\n %s; \n}\n", c) }
Boundary = [^a-zA-Z_0-9]
Keyword = < Boundary (
'elseif' | 'if' | 'else' | 'while' | 'class' |
'echo' | 'print' | 'return' | 'in' | 'global' |
'static' | 'new' | 'continue' | 'next' | 'break'
) Boundary > { DUP }
Method = v:Literal '.' m:Id '(' - a:Literal { printf("__send__('%s', %s, %s", m, v, a) }
| v:Literal '.' m:Id '(' - ')' { printf("__send__('%s', %s)", m, v) }
| v:Literal - m:Binop - a:Literal { printf("__send__('%s', %s, %s)", m, v, a) }
| v:Literal '[' - (a:Literal | a:Null) - ']'
- '=' - b:Literal { printf("__send__('[]=', %s, %s, %s)", v, a, b) }
| v:Literal '[' - a:Literal - ']' { printf("__send__('[]', %s, %s)", v, a) }
Binop = < (
'<<' | '>>' |
'+=' | '-=' | '/=' | '*=' | '%=' | '<=' | '>=' |
'+' | '-' | '/' | '*' | '%' | '<' | '>' |
'^' | '^=' | '&' | '&=' | '|' | '|=' | '#'
) > { DUP }
Literal = String
| Float
| Int
| Var
String = String_s | String_d
Function = '-' - v:Id - '(' { printf("function %s(", v) }
Define = c:Constant - '=' - v:Literal { printf("define('%s', %s)", c, v) }
Accessor = '.' n:Id { printf("->%s", n) }
Each = 'for' s k:Var s v:Var s 'in' s e:Var { printf("foreach((array) %s as %s => %s)", e, k, v) }
| 'for' s v:Var s 'in' s e:Var { printf("foreach((array) %s as %s)", e, v) }
Unless = 'unless'
- '(' < (!')' .)+ > ')' { printf("if (!(%s))", yytext) }
ArrayPair = &{ in_array } v:Id ':' { printf("'%s' =>", v) }
| &{ in_array } v:Literal - ':' { printf("%s =>", v) }
Array = '[' { printf("array("); in_array = 1 }
| ']' { printf(")"); in_array = 0 }
Null = '' { $$ = strdup("null") }
Cast = '(' v:Id ')' { printf("(%s)", v) }
Var = v:Id { VAR }
Comment = '---' (!'---' .)* '---'
String_s = < '\'' (!'\'' .)* '\'' > { DUP }
String_d = < '"' (!'"' .)* '"' > { DUP }
Float = < [0-9]+ '.' [0-9]+ > { DUP }
Int = < [0-9]+ > { DUP }
Constant = < [A-Z] [a-zA-Z0-9_]* > { DUP }
Id = < [a-z_] [a-zA-Z0-9_]* > { DUP }
Char = < [a-zA-Z] > { DUP }
Newline = '\n' | '\r\n' | '\r'
EOL = Newline | EOF
EOF = !.
s = [ \t]+
- = [ \t]*
%%
int
main(int argc, char **argv) {
if (argv[1] && strcmp(argv[1], "--help") != -1) usage();
else while (yyparse()) ;
return 0;
}
void
usage() {
printf(
"\n"
" llp - Less Lame PHP %s\n\n"
" Usage:\n"
" llp < in.llp > out.php\n\n", LLP_VERSION);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment