diff -uNr kmyacc-4.1.4-org/sample/calc.phpy kmyacc-4.1.4-php/sample/calc.phpy --- kmyacc-4.1.4-org/sample/calc.phpy 1970-01-01 09:00:00.000000000 +0900 +++ kmyacc-4.1.4-php/sample/calc.phpy 2008-01-28 01:20:53.000000000 +0900 @@ -0,0 +1,59 @@ +/* + * calculator + */ + +%token NUMBER + +%left '+' '-' +%left '*' '/' + +%% + +start: lines; + +lines: /* empty */ + | lines line + ; + +line : expr '\n' { echo $1."\n"; } + | '\n' { echo "(empty line ignored)\n"; } + | error '\n' + ; + +expr : expr '+' expr { $$ = $1 + $3; } + | expr '-' expr { $$ = $1 - $3; } + | expr '*' expr { $$ = $1 * $3; } + | expr '/' expr { $$ = $1 / $3; } + | '(' expr ')' { $$ = $2; } + | NUMBER { $$ = $1; } + ; + +%% + +$lexbuf = ''; + +function yylex() +{ + global $lexbuf, $yylval; + + do { + preg_replace('/^[\t ]+/', '', $lexbuf); + if ($lexbuf) break; + } while ($lexbuf = fgets(STDIN)); + + if (preg_match('/^(\d+)/', $lexbuf, $matches)) { + $yylval = (int)$matches[1]; + $lexbuf = substr($lexbuf, strlen($matches[1])); + return NUMBER; + } else { + $ret = ord($lexbuf); + $lexbuf = substr($lexbuf, 1); + return $ret; + } +} + +function yyerror() +{ +} + +yyparse(); diff -uNr kmyacc-4.1.4-org/sample/calc.pyy kmyacc-4.1.4-php/sample/calc.pyy --- kmyacc-4.1.4-org/sample/calc.pyy 1970-01-01 09:00:00.000000000 +0900 +++ kmyacc-4.1.4-php/sample/calc.pyy 2008-01-26 13:16:50.000000000 +0900 @@ -0,0 +1,84 @@ +/* Calculator in kmyacc + Python. */ + +%{ +%} + + +%token NUMBER IDENTIFIER + +%left '+' '-' +%left '*' '/' + +%% + +start: line; + +/* +lines: + | lines line { $$ = $1 + $2 } + ; +*/ + +line : expr { print $1 } + | { $$ = "(empty line ignored)" } + | error { $$ = "" } + ; + +expr : expr '+' expr { $$ = $1 + $3 } + | expr '-' expr { $$ = $1 - $3 } + | expr '*' expr { $$ = $1 * $3 } + | expr '/' expr { $$ = $1 / $3 } + | '(' expr ')' { $$ = $2 } + | NUMBER { $$ = $1 } + ; + +%% + +''' Lexical analyzer ''' + +buffer = "1+2*3" +token = None +toktype = None + + +def isletter(c): + return (ord('a') <= ord(c) and ord(c) <= ord('z')) or (ord('A') <= ord(c) and ord(c) <= ord('Z')) + +def isdigit(c): + return (ord('0') <= ord(c) and ord(c) <= ord('9')) + +def yylex(): + global buffer, token, toktype, yylval + while len(buffer) > 0 and (buffer[0] == ' ' or buffer[0] == '\t'): + buffer = buffer[1:] + if len(buffer) == 0: + return 0 + if isletter(buffer[0]): + i = 0 + while i < len(buffer): + if not isletter(buffer[i]) and not isdigit(buffer[i]): + break + i = i + 1 + token = buffer[:i] + buffer = buffer[i:] + return IDENTIFIER + elif isdigit(buffer[0]): + i = 0 + while i < len(buffer): + if not isdigit(buffer[i]): + break + i = i + 1 + token = buffer[:i] + buffer = buffer[i:] + yylval = int(token) + return NUMBER + else: + token = buffer[:1] + buffer = buffer[1:] + return ord(token[0]) + +def yyerror(msg): + yyprintln(msg) + +print buffer +yyparse() diff -uNr kmyacc-4.1.4-org/src/Makefile kmyacc-4.1.4-php/src/Makefile --- kmyacc-4.1.4-org/src/Makefile 2008-01-26 13:16:47.000000000 +0900 +++ kmyacc-4.1.4-php/src/Makefile 2008-01-28 01:24:24.000000000 +0900 @@ -44,6 +44,8 @@ $(INSTALL) kmyacc.java.parser $(PARLIB) $(INSTALL) kmyacc.js.parser $(PARLIB) $(INSTALL) kmyacc.pl.parser $(PARLIB) + $(INSTALL) kmyacc.py.parser $(PARLIB) + $(INSTALL) kmyacc.php.parser $(PARLIB) diff -uNr kmyacc-4.1.4-org/src/common.h kmyacc-4.1.4-php/src/common.h --- kmyacc-4.1.4-org/src/common.h 2008-01-26 13:16:46.000000000 +0900 +++ kmyacc-4.1.4-php/src/common.h 2008-01-26 13:16:49.000000000 +0900 @@ -6,6 +6,7 @@ typedef unsigned char uchar; +typedef unsigned int uint; typedef int bool; #define YES 1 diff -uNr kmyacc-4.1.4-org/src/genparser.c kmyacc-4.1.4-php/src/genparser.c --- kmyacc-4.1.4-org/src/genparser.c 2008-01-26 13:16:47.000000000 +0900 +++ kmyacc-4.1.4-php/src/genparser.c 2008-01-26 13:16:49.000000000 +0900 @@ -35,6 +35,8 @@ #define LANG_RUBY 4 #define LANG_JS 5 #define LANG_ML 6 +#define LANG_PYTHON 7 +#define LANG_PHP 8 #endif /* global */ @@ -99,6 +101,8 @@ { LANG_RUBY, "ruby", ".rb", ".rby" }, { LANG_JS, "javascript", ".js", ".jsy" }, { LANG_ML, "ml", ".ml", ".mly" }, + { LANG_PHP, "py", ".py", ".pyy" }, + { LANG_PHP, "php", ".php", ".phpy" }, { -1, NULL, NULL, NULL } }; @@ -343,6 +347,7 @@ return "byte"; default: unsupported(); + return 0; // Remove compiler warning } } @@ -356,11 +361,17 @@ fprintf(ofp, "%s", indent); fprintf(ofp, i + 1 == n ? "%5d" : "%5d,", p[i]); if (++col == 10) { + if(get_lang_id() == LANG_PYTHON) + fprintf(ofp, " \\"); fprintf(ofp, "\n"); col = 0; } } - if (col != 0) fprintf(ofp, "\n"); + if (col != 0) { + if(get_lang_id() == LANG_PYTHON) + fprintf(ofp, " \\"); + fprintf(ofp, "\n"); + } } diff -uNr kmyacc-4.1.4-org/src/genparser.h kmyacc-4.1.4-php/src/genparser.h --- kmyacc-4.1.4-org/src/genparser.h 2008-01-26 13:16:46.000000000 +0900 +++ kmyacc-4.1.4-php/src/genparser.h 2008-01-26 13:16:48.000000000 +0900 @@ -9,6 +9,8 @@ #define LANG_RUBY 4 #define LANG_JS 5 #define LANG_ML 6 +#define LANG_PYTHON 7 +#define LANG_PHP 8 extern char *get_lang_name(void); extern int get_lang_id(void); diff -uNr kmyacc-4.1.4-org/src/grammar.c kmyacc-4.1.4-php/src/grammar.c --- kmyacc-4.1.4-org/src/grammar.c 2008-01-26 13:16:47.000000000 +0900 +++ kmyacc-4.1.4-php/src/grammar.c 2008-01-26 23:34:32.000000000 +0900 @@ -392,10 +392,10 @@ int val; nterms = nnonts = 0; - intern_gsym("$EOF", YES); + intern_gsym(get_lang_id() == LANG_PHP ? "EOF" : "$EOF", YES); gsym[0]->value = 0; error_token = intern_gsym(intern_token("error"), YES); - start_prime = intern_gsym("$start", NO); + start_prime = intern_gsym(get_lang_id() == LANG_PHP ? "start" : "$start", NO); start_sym = 0; cur_prec = 0; unioned = NO; diff -uNr kmyacc-4.1.4-org/src/kmyacc.php.parser kmyacc-4.1.4-php/src/kmyacc.php.parser --- kmyacc-4.1.4-org/src/kmyacc.php.parser 1970-01-01 09:00:00.000000000 +0900 +++ kmyacc-4.1.4-php/src/kmyacc.php.parser 2008-01-27 23:49:23.000000000 +0900 @@ -0,0 +1,348 @@ += 0 + && $yyn < YYLAST && $yycheck[$yyn] == $yychar + || ($yystate < YY2TBLSTATE + && ($yyn = $yybase[$yystate + YYNLSTATES] + $yychar) >= 0 + && $yyn < YYLAST && $yycheck[$yyn] == $yychar)) + && ($yyn = $yyaction[$yyn]) != YYDEFAULT) { + /* + * >= YYNLSTATE: shift and reduce + * > 0: shift + * = 0: accept + * < 0: reduce + * = -YYUNEXPECTED: error + */ + if ($yyn > 0) { + /* shift */ +@if -t + YYTRACE_SHIFT($yychar); +@endif + $yysp++; + + $yysstk[$yysp] = $yystate = $yyn; + $yyastk[$yysp] = $yylval; + $yychar = -1; + + if ($yyerrflag > 0) + $yyerrflag--; + if ($yyn < YYNLSTATES) + continue; + + /* $yyn >= YYNLSTATES means shift-and-reduce */ + $yyn -= YYNLSTATES; + } else + $yyn = -$yyn; + } else + $yyn = $yydefault[$yystate]; + } + + while (true) { + /* reduce/error */ + if ($yyn == 0) { + /* accept */ +@if -t + YYTRACE_ACCEPT(); +@endif + yyflush(); + return 0; + } + else if ($yyn != YYUNEXPECTED) { + /* reduce */ + $yyl = $yylen[$yyn]; + $n = $yysp-$yyl+1; + $yyval = isset($yyastk[$n]) ? $yyastk[$n] : null; +@if -t + YYTRACE_REDUCE($yyn); +@endif + /* Following line will be replaced by reduce actions */ + switch($yyn) { +@reduce + case %n: +{%b} break; +@endreduce + } + /* Goto - shift nonterminal */ + $yysp -= $yyl; + $yyn = $yylhs[$yyn]; + if (($yyp = $yygbase[$yyn] + $yysstk[$yysp]) >= 0 && $yyp < YYGLAST + && $yygcheck[$yyp] == $yyn) + $yystate = $yygoto[$yyp]; + else + $yystate = $yygdefault[$yyn]; + + $yysp++; + + $yysstk[$yysp] = $yystate; + $yyastk[$yysp] = $yyval; + } + else { + /* error */ + switch ($yyerrflag) { + case 0: + yyerror("syntax error"); + case 1: + case 2: + $yyerrflag = 3; + /* Pop until error-expecting state uncovered */ + + while (!(($yyn = $yybase[$yystate] + YYINTERRTOK) >= 0 + && $yyn < YYLAST && $yycheck[$yyn] == YYINTERRTOK + || ($yystate < YY2TBLSTATE + && ($yyn = $yybase[$yystate + YYNLSTATES] + YYINTERRTOK) >= 0 + && $yyn < YYLAST && $yycheck[$yyn] == YYINTERRTOK))) { + if ($yysp <= 0) { + yyflush(); + return 1; + } + $yystate = $yysstk[--$yysp]; +@if -t + YYTRACE_POP($yystate); +@endif + } + $yyn = $yyaction[$yyn]; +@if -t + YYTRACE_SHIFT(YYINTERRTOK); +@endif + $yysstk[++$yysp] = $yystate = $yyn; + break; + + case 3: +@if -t + YYTRACE_DISCARD($yychar); +@endif + if ($yychar == 0) { + yyflush(); + return 1; + } + $yychar = -1; + break; + } + } + + if ($yystate < YYNLSTATES) + break; + /* >= YYNLSTATES means shift-and-reduce */ + $yyn = $yystate - YYNLSTATES; + } + } +} + +@tailcode; diff -uNr kmyacc-4.1.4-org/src/kmyacc.py.parser kmyacc-4.1.4-php/src/kmyacc.py.parser --- kmyacc-4.1.4-org/src/kmyacc.py.parser 1970-01-01 09:00:00.000000000 +0900 +++ kmyacc-4.1.4-php/src/kmyacc.py.parser 2008-01-26 13:16:49.000000000 +0900 @@ -0,0 +1,311 @@ +$semval($) yyval +$semval($,%t) yyval +$semval(%n) yyastk[yysp-(%l-%n)] +$semval(%n,%t) yyastk[yysp-(%l-%n)] +$include + +''' +Prototype file of Python parser. +Written by Yu Kobayashi +This file is PUBLIC DOMAIN. +''' + +buffer = "" +token = "" +toktype = "" +YYDEFAULTSTACK = 512 + +$tokenval +%s = %n +$endtokenval + + +''' + #define yyclearin (yychar = -1) + #define yyerrok (yyerrflag = 0) + #define YYRECOVERING (yyerrflag != 0) + #define YYERROR goto yyerrlab +''' + + +''' Debug mode flag ''' +yydebug = False + +''' lexical element object ''' +yylval = None + +def yyprintln(msg): + print msg + +def yyflush(): + dummy = 0 + +$if -t +yydebug = True + +yyterminals = [ \ + $listvar terminals \ + , "???" \ + ] + + +def yytokname(n) : + switch (n) : + $switch-for-token-name + default: + return "???" + +yyproduction = [ \ + $production-strings \ +] + + +''' Traditional Debug Mode ''' +def YYTRACE_NEWSTATE(state, sym): + if yydebug: + yyprintln("% State " + state + ", Lookahead " + (sym < 0 ? "--none--" : yyterminals[sym])) + +def YYTRACE_READ(sym): + if yydebug: + yyprintln("% Reading " + yyterminals[sym]) + +def YYTRACE_SHIFT(sym): + if yydebug: + yyprintln("% Shift " + yyterminals[sym]) + +def YYTRACE_ACCEPT(): + if (yydebug) : + yyprintln("% Accepted.") + +def YYTRACE_REDUCE(n): + if yydebug: + yyprintln("% Reduce by (" + n + ") " + yyproduction[n]) + +def YYTRACE_POP(state): + if yydebug: + yyprintln("% Recovering, uncovers state " + state) + +def YYTRACE_DISCARD(sym): + if yydebug: + yyprintln("% Discard " + yyterminals[sym]) +$endif + + +yytranslate = [ \ + $listvar yytranslate \ + ] + +YYBADCH = $(YYBADCH) +YYMAXLEX = $(YYMAXLEX) +YYTERMS = $(YYTERMS) +YYNONTERMS = $(YYNONTERMS) + +yyaction = [ \ + $listvar yyaction \ + ] + +YYLAST = $(YYLAST) + +yycheck = [ \ + $listvar yycheck \ + ] + +yybase = [ \ + $listvar yybase \ + ] + +YY2TBLSTATE = $(YY2TBLSTATE) + +yydefault = [ \ + $listvar yydefault \ + ] + + + +yygoto = [ \ + $listvar yygoto \ + ] + +YYGLAST = $(YYGLAST) + +yygcheck = [ \ + $listvar yygcheck \ + ] + +yygbase = [ \ + $listvar yygbase \ + ] + +yygdefault = [ \ + $listvar yygdefault \ + ] + +yylhs = [ \ + $listvar yylhs \ + ] + +yylen = [ \ + $listvar yylen \ + ] + +YYSTATES = $(YYSTATES) +YYNLSTATES = $(YYNLSTATES) +YYINTERRTOK = $(YYINTERRTOK) +YYUNEXPECTED = $(YYUNEXPECTED) +YYDEFAULT = $(YYDEFAULT) + +''' +Parser entry point +''' + +def yyparse(): + yyastk = range(YYDEFAULTSTACK) + yysstk = range(YYDEFAULTSTACK) + + yystate = 0 + yychar = -1 + + yysp = 0 + yysstk[yysp] = 0 + yyerrflag = 0 + while True: +$if -t + YYTRACE_NEWSTATE(yystate, yychar) +$endif + if yybase[yystate] == 0: + yyn = yydefault[yystate] + else: + if yychar < 0: + yychar = yylex() + if yychar <= 0: + yychar = 0 + if yychar < YYMAXLEX: + yychar = yytranslate[yychar] + else: + yychar = YYBADCH +$if -t + YYTRACE_READ(yychar) +$endif + yyn = yybase[yystate] + yychar + goNext = yyn >= 0 and yyn < YYLAST and yycheck[yyn] == yychar + if not goNext: + goNext = yystate < YY2TBLSTATE + if goNext: + yyn = yybase[yystate + YYNLSTATES] + yychar + goNext = yyn >= 0 and yyn < YYLAST and yycheck[yyn] == yychar + if goNext: + yyn = yyaction[yyn] + goNext = yyn != YYDEFAULT + if goNext: + ''' + >= YYNLSTATE: shift and reduce + > 0: shift + = 0: accept + < 0: reduce + = -YYUNEXPECTED: error + ''' + if yyn > 0 : + ''' shift ''' +$if -t + YYTRACE_SHIFT(yychar) +$endif + yysp = yysp + 1 + + yysstk[yysp] = yystate = yyn + yyastk[yysp] = yylval + yychar = -1 + + if yyerrflag > 0: + yyerrflag = yyerrflag - 1 + if yyn < YYNLSTATES: + continue + + ''' yyn >= YYNLSTATES means shift-and-reduce ''' + yyn -= YYNLSTATES + else: + yyn = -yyn + else: + yyn = yydefault[yystate] + + while True: + ''' reduce/error ''' + if yyn == 0: + ''' accept ''' +$if -t + YYTRACE_ACCEPT() +$endif + yyflush() + return 0 + elif yyn != YYUNEXPECTED: + ''' reduce ''' + yyl = yylen[yyn] + yyval = yyastk[yysp-yyl+1] +$if -t + YYTRACE_REDUCE(yyn) +$endif + ''' Following line will be replaced by reduce actions ''' +$reduce + if yyn == %n: + %b +$endreduce + ''' Goto - shift nonterminal ''' + yysp -= yyl + yyn = yylhs[yyn] + yyp = yygbase[yyn] + yysstk[yysp] + if yyp >= 0 and yyp < YYGLAST and yygcheck[yyp] == yyn: + yystate = yygoto[yyp] + else: + yystate = yygdefault[yyn] + + yysp = yysp + 1 + + yysstk[yysp] = yystate + yyastk[yysp] = yyval + else : + ''' error ''' + if yyerrflag == 0: + yyerror("syntax error") + if yyerrflag == 0 or yyerrflat == 1 or yyerrflag == 2: + yyerrflag = 3 + ''' Pop until error-expecting state uncovered ''' + + while True: + yyn = yybase[yystate] + YYINTERRTOK + b = yyn >= 0 and yyn < YYLAST and yycheck[yyn] == YYINTERRTOK + if not b: + b = yystate < YY2TBLSTATE + if b: + yyn = yybase[yystate + YYNLSTATES] + YYINTERRTOK + b = yyn >= 0 and yyn < YYLAST and yycheck[yyn] == YYINTERRTOK + if not b: + break + if yysp <= 0: + yyflush() + return 1 + yysp = yysp - 1 + yystate = yysstk[yysp] +$if -t + YYTRACE_POP(yystate) +$endif + yyn = yyaction[yyn] +$if -t + YYTRACE_SHIFT(YYINTERRTOK) +$endif + yysp = yysp + 1 + yystate = yyn + yysstk[yysp] = yyn + elif yyerrflatcase == 3: +$if -t + YYTRACE_DISCARD(yychar) +$endif + if yychar == 0 : + yyflush() + return 1 + yychar = -1 + + if yystate < YYNLSTATES: + break + ''' >= YYNLSTATES means shift-and-reduce ''' + yyn = yystate - YYNLSTATES + +$tailcode