Created
December 11, 2017 17:32
-
-
Save stenin-nikita/bc6724e4f100e3afe170121c2f4b4c56 to your computer and use it in GitHub Desktop.
kmyacc example
This file contains 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
<?php | |
/* Prototype file of PHP parser. | |
* Written by Masato Bito | |
* This file is PUBLIC DOMAIN. | |
*/ | |
$buffer = null; | |
$token = null; | |
$toktype = null; | |
define('YYERRTOK', 256); | |
define('NUMBER', 257); | |
/* | |
#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 = null; | |
function yyprintln($msg) | |
{ | |
echo "$msg\n"; | |
} | |
function yyflush() | |
{ | |
return; | |
} | |
$yytranslate = array( | |
0, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
7, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
8, 9, 5, 3, 10, 4, 10, 6, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, | |
10, 10, 10, 10, 10, 10, 1, 2 | |
); | |
define('YYBADCH', 10); | |
define('YYMAXLEX', 258); | |
define('YYTERMS', 10); | |
define('YYNONTERMS', 5); | |
$yyaction = array( | |
19, -1, 12, 7, 8, 5, 6, 0, 18, 5, | |
6, 24, 25, 17, 0, 0, 0, 0, 4 | |
); | |
define('YYLAST', 19); | |
$yycheck = array( | |
7, 0, 1, 5, 6, 3, 4, 0, 7, 3, | |
4, 9, 2, 7, -1, -1, -1, -1, 8 | |
); | |
$yybase = array( | |
0, 1, 6, 2, 10, 10, 10, 10, 10, -2, | |
-2, 7, -7, 0, 10, -2, -2 | |
); | |
define('YY2TBLSTATE', 4); | |
$yydefault = array( | |
2,32767,32767,32767,32767,32767,32767,32767,32767, 7, | |
8,32767,32767 | |
); | |
$yygoto = array( | |
3, 9, 10, 22, 23 | |
); | |
define('YYGLAST', 5); | |
$yygcheck = array( | |
4, 4, 4, 4, 4 | |
); | |
$yygbase = array( | |
0, 0, 0, 0, -4 | |
); | |
$yygdefault = array( | |
-32768, 11, 1, 16, 2 | |
); | |
$yylhs = array( | |
0, 1, 2, 2, 3, 3, 3, 4, 4, 4, | |
4, 4, 4 | |
); | |
$yylen = array( | |
1, 1, 0, 2, 2, 1, 2, 3, 3, 3, | |
3, 3, 1 | |
); | |
define('YYSTATES', 21); | |
define('YYNLSTATES', 13); | |
define('YYINTERRTOK', 1); | |
define('YYUNEXPECTED', 32767); | |
define('YYDEFAULT', -32766); | |
/* | |
* Parser entry point | |
*/ | |
function yyparse() | |
{ | |
global $buffer, $token, $toktype, $yyaction, $yybase, $yycheck, $yydebug, | |
$yydebug, $yydefault, $yygbase, $yygcheck, $yygdefault, $yygoto, $yylen, | |
$yylhs, $yylval, $yyproduction, $yyterminals, $yytranslate; | |
$yyastk = array(); | |
$yysstk = array(); | |
$yyn = $yyl = 0; | |
$yystate = 0; | |
$yychar = -1; | |
$yysp = 0; | |
$yysstk[$yysp] = 0; | |
$yyerrflag = 0; | |
while (true) { | |
if ($yybase[$yystate] == 0) | |
$yyn = $yydefault[$yystate]; | |
else { | |
if ($yychar < 0) { | |
if (($yychar = yylex()) <= 0) $yychar = 0; | |
$yychar = $yychar < YYMAXLEX ? $yytranslate[$yychar] : YYBADCH; | |
} | |
if ((($yyn = $yybase[$yystate] + $yychar) >= 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 */ | |
$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 */ | |
yyflush(); | |
return 0; | |
} | |
else if ($yyn != YYUNEXPECTED) { | |
/* reduce */ | |
$yyl = $yylen[$yyn]; | |
$n = $yysp-$yyl+1; | |
$yyval = isset($yyastk[$n]) ? $yyastk[$n] : null; | |
/* Following line will be replaced by reduce actions */ | |
switch($yyn) { | |
case 4: | |
{ echo $yyastk[$yysp-(2-1)]."\n"; } break; | |
case 5: | |
{ echo "(empty line ignored)\n"; } break; | |
case 7: | |
{ $yyval = $yyastk[$yysp-(3-1)] + $yyastk[$yysp-(3-3)]; } break; | |
case 8: | |
{ $yyval = $yyastk[$yysp-(3-1)] - $yyastk[$yysp-(3-3)]; } break; | |
case 9: | |
{ $yyval = $yyastk[$yysp-(3-1)] * $yyastk[$yysp-(3-3)]; } break; | |
case 10: | |
{ $yyval = $yyastk[$yysp-(3-1)] / $yyastk[$yysp-(3-3)]; } break; | |
case 11: | |
{ $yyval = $yyastk[$yysp-(3-2)]; } break; | |
case 12: | |
{ $yyval = $yyastk[$yysp-(1-1)]; } break; | |
} | |
/* 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]; | |
} | |
$yyn = $yyaction[$yyn]; | |
$yysstk[++$yysp] = $yystate = $yyn; | |
break; | |
case 3: | |
if ($yychar == 0) { | |
yyflush(); | |
return 1; | |
} | |
$yychar = -1; | |
break; | |
} | |
} | |
if ($yystate < YYNLSTATES) | |
break; | |
/* >= YYNLSTATES means shift-and-reduce */ | |
$yyn = $yystate - YYNLSTATES; | |
} | |
} | |
} | |
$lexbuf = ''; | |
function yylex() | |
{ | |
global $lexbuf, $yylval; | |
do { | |
$lexbuf = preg_replace('/^[\t ]+/', '', $lexbuf); | |
if ($lexbuf) break; | |
} while ($lexbuf = fgets(STDIN)); | |
$lexbuf = str_replace(PHP_EOL, "\n", $lexbuf); | |
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($msg) | |
{ | |
print($msg); | |
} | |
yyparse(); |
This file contains 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
/* | |
* 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 { | |
$lexbuf = preg_replace('/^[\t ]+/', '', $lexbuf); | |
if ($lexbuf) break; | |
} while ($lexbuf = fgets(STDIN)); | |
$lexbuf = str_replace(PHP_EOL, "\n", $lexbuf); | |
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($msg) | |
{ | |
print($msg); | |
} | |
yyparse(); |
This file contains 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
<?php | |
$meta @ | |
@semval($) $yyval | |
@semval($,%t) $yyval | |
@semval(%n) $yyastk[$yysp-(%l-%n)] | |
@semval(%n,%t) $yyastk[$yysp-(%l-%n)] | |
@include; | |
/* Prototype file of PHP parser. | |
* Written by Masato Bito | |
* This file is PUBLIC DOMAIN. | |
*/ | |
$buffer = null; | |
$token = null; | |
$toktype = null; | |
@tokenval | |
define('%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 = null; | |
function yyprintln($msg) | |
{ | |
echo "$msg\n"; | |
} | |
function yyflush() | |
{ | |
return; | |
} | |
@if -t | |
$yydebug = true; | |
$yyterminals = array( | |
@listvar terminals | |
, "???" | |
); | |
function yytokname($n) | |
{ | |
switch ($n) { | |
@switch-for-token-name; | |
default: | |
return "???"; | |
} | |
} | |
$yyproduction = array( | |
@production-strings; | |
); | |
/* Traditional Debug Mode */ | |
function YYTRACE_NEWSTATE($state, $sym) | |
{ | |
global $yydebug, $yyterminals; | |
if ($yydebug) | |
yyprintln("% State " . $state . ", Lookahead " | |
. ($sym < 0 ? "--none--" : $yyterminals[$sym])); | |
} | |
function YYTRACE_READ($sym) | |
{ | |
global $yydebug, $yyterminals; | |
if ($yydebug) | |
yyprintln("% Reading " . $yyterminals[$sym]); | |
} | |
function YYTRACE_SHIFT($sym) | |
{ | |
global $yydebug, $yyterminals; | |
if ($yydebug) | |
yyprintln("% Shift " . $yyterminals[$sym]); | |
} | |
function YYTRACE_ACCEPT() | |
{ | |
global $yydebug; | |
if ($yydebug) yyprintln("% Accepted."); | |
} | |
function YYTRACE_REDUCE($n) | |
{ | |
global $yydebug, $yyproduction; | |
if ($yydebug) | |
yyprintln("% Reduce by (" . $n . ") " . $yyproduction[$n]); | |
} | |
function YYTRACE_POP($state) | |
{ | |
global $yydebug; | |
if ($yydebug) | |
yyprintln("% Recovering, uncovers state " . $state); | |
} | |
function YYTRACE_DISCARD($sym) | |
{ | |
global $yydebug, $yyterminals; | |
if ($yydebug) | |
yyprintln("% Discard " . $yyterminals[$sym]); | |
} | |
@endif | |
$yytranslate = array( | |
@listvar yytranslate | |
); | |
define('YYBADCH', @(YYBADCH)); | |
define('YYMAXLEX', @(YYMAXLEX)); | |
define('YYTERMS', @(YYTERMS)); | |
define('YYNONTERMS', @(YYNONTERMS)); | |
$yyaction = array( | |
@listvar yyaction | |
); | |
define('YYLAST', @(YYLAST)); | |
$yycheck = array( | |
@listvar yycheck | |
); | |
$yybase = array( | |
@listvar yybase | |
); | |
define('YY2TBLSTATE', @(YY2TBLSTATE)); | |
$yydefault = array( | |
@listvar yydefault | |
); | |
$yygoto = array( | |
@listvar yygoto | |
); | |
define('YYGLAST', @(YYGLAST)); | |
$yygcheck = array( | |
@listvar yygcheck | |
); | |
$yygbase = array( | |
@listvar yygbase | |
); | |
$yygdefault = array( | |
@listvar yygdefault | |
); | |
$yylhs = array( | |
@listvar yylhs | |
); | |
$yylen = array( | |
@listvar yylen | |
); | |
define('YYSTATES', @(YYSTATES)); | |
define('YYNLSTATES', @(YYNLSTATES)); | |
define('YYINTERRTOK', @(YYINTERRTOK)); | |
define('YYUNEXPECTED', @(YYUNEXPECTED)); | |
define('YYDEFAULT', @(YYDEFAULT)); | |
/* | |
* Parser entry point | |
*/ | |
function yyparse() | |
{ | |
global $buffer, $token, $toktype, $yyaction, $yybase, $yycheck, $yydebug, | |
$yydebug, $yydefault, $yygbase, $yygcheck, $yygdefault, $yygoto, $yylen, | |
$yylhs, $yylval, $yyproduction, $yyterminals, $yytranslate; | |
$yyastk = array(); | |
$yysstk = array(); | |
$yyn = $yyl = 0; | |
$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) { | |
if (($yychar = yylex()) <= 0) $yychar = 0; | |
$yychar = $yychar < YYMAXLEX ? $yytranslate[$yychar] : YYBADCH; | |
@if -t | |
YYTRACE_READ($yychar); | |
@endif | |
} | |
if ((($yyn = $yybase[$yystate] + $yychar) >= 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; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment