mirror of https://github.com/vitalif/lime
The error token works now.
parent
1b7c30f7b8
commit
e68b476c09
|
@ -1,438 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
*** DON'T EDIT THIS FILE! ***
|
||||
*
|
||||
* This file was automatically generated by the Lime parser generator.
|
||||
* The real source code you should be looking at is in one or more
|
||||
* grammar files in the Lime format.
|
||||
*
|
||||
* THE ONLY REASON TO LOOK AT THIS FILE is to see where in the grammar
|
||||
* file that your error happened, because there are enough comments to
|
||||
* help you debug your grammar.
|
||||
|
||||
* If you ignore this warning, you're shooting yourself in the brain,
|
||||
* not the foot.
|
||||
*/
|
||||
class calc extends lime_parser {
|
||||
public $qi = 0;
|
||||
public $i = array(
|
||||
array(
|
||||
'exp' => 's 1',
|
||||
'var' => 's 23',
|
||||
'num' => 's 3',
|
||||
"'+'" => 's 16',
|
||||
"'-'" => 's 18',
|
||||
"'('" => 's 20',
|
||||
'stmt' => 's 26',
|
||||
"'start'" => "a 'start'"
|
||||
),
|
||||
array(
|
||||
"'+'" => 's 2',
|
||||
"'-'" => 's 6',
|
||||
"'*'" => 's 8',
|
||||
"'/'" => 's 10',
|
||||
"'^'" => 's 12',
|
||||
"'%'" => 's 14',
|
||||
'#' => 'r 0'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 5',
|
||||
"'+'" => 's 16',
|
||||
"'-'" => 's 18',
|
||||
"'('" => 's 20'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 2',
|
||||
"'-'" => 'r 2',
|
||||
"'*'" => 'r 2',
|
||||
"'/'" => 'r 2',
|
||||
"'^'" => 'r 2',
|
||||
"'%'" => 'r 2',
|
||||
"')'" => 'r 2',
|
||||
'#' => 'r 2'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 3',
|
||||
"'-'" => 'r 3',
|
||||
"'*'" => 'r 3',
|
||||
"'/'" => 'r 3',
|
||||
"'^'" => 'r 3',
|
||||
"'%'" => 'r 3',
|
||||
"')'" => 'r 3',
|
||||
'#' => 'r 3'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 4',
|
||||
"'-'" => 'r 4',
|
||||
"'*'" => 's 8',
|
||||
"'/'" => 's 10',
|
||||
"'^'" => 's 12',
|
||||
"'%'" => 's 14',
|
||||
"')'" => 'r 4',
|
||||
'#' => 'r 4'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 7',
|
||||
"'+'" => 's 16',
|
||||
"'-'" => 's 18',
|
||||
"'('" => 's 20'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 5',
|
||||
"'-'" => 'r 5',
|
||||
"'*'" => 's 8',
|
||||
"'/'" => 's 10',
|
||||
"'^'" => 's 12',
|
||||
"'%'" => 's 14',
|
||||
"')'" => 'r 5',
|
||||
'#' => 'r 5'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 9',
|
||||
"'+'" => 's 16',
|
||||
"'-'" => 's 18',
|
||||
"'('" => 's 20'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 6',
|
||||
"'-'" => 'r 6',
|
||||
"'*'" => 'r 6',
|
||||
"'/'" => 'r 6',
|
||||
"'^'" => 's 12',
|
||||
"'%'" => 'r 6',
|
||||
"')'" => 'r 6',
|
||||
'#' => 'r 6'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 11',
|
||||
"'+'" => 's 16',
|
||||
"'-'" => 's 18',
|
||||
"'('" => 's 20'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 7',
|
||||
"'-'" => 'r 7',
|
||||
"'*'" => 'r 7',
|
||||
"'/'" => 'r 7',
|
||||
"'^'" => 's 12',
|
||||
"'%'" => 'r 7',
|
||||
"')'" => 'r 7',
|
||||
'#' => 'r 7'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 13',
|
||||
"'+'" => 's 16',
|
||||
"'-'" => 's 18',
|
||||
"'('" => 's 20'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 8',
|
||||
"'-'" => 'r 8',
|
||||
"'*'" => 'r 8',
|
||||
"'/'" => 'r 8',
|
||||
"'^'" => 's 12',
|
||||
"'%'" => 'r 8',
|
||||
"')'" => 'r 8',
|
||||
'#' => 'r 8'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 15',
|
||||
"'+'" => 's 16',
|
||||
"'-'" => 's 18',
|
||||
"'('" => 's 20'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 9',
|
||||
"'-'" => 'r 9',
|
||||
"'*'" => 'r 9',
|
||||
"'/'" => 'r 9',
|
||||
"'^'" => 's 12',
|
||||
"'%'" => 'r 9',
|
||||
"')'" => 'r 9',
|
||||
'#' => 'r 9'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 17',
|
||||
"'+'" => 's 16',
|
||||
"'-'" => 's 18',
|
||||
"'('" => 's 20'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 10',
|
||||
"'-'" => 'r 10',
|
||||
"'*'" => 'r 10',
|
||||
"'/'" => 'r 10',
|
||||
"'^'" => 'r 10',
|
||||
"'%'" => 'r 10',
|
||||
"')'" => 'r 10',
|
||||
'#' => 'r 10'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 19',
|
||||
"'+'" => 's 16',
|
||||
"'-'" => 's 18',
|
||||
"'('" => 's 20'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 11',
|
||||
"'-'" => 'r 11',
|
||||
"'*'" => 'r 11',
|
||||
"'/'" => 'r 11',
|
||||
"'^'" => 'r 11',
|
||||
"'%'" => 'r 11',
|
||||
"')'" => 'r 11',
|
||||
'#' => 'r 11'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 21',
|
||||
"'+'" => 's 16',
|
||||
"'-'" => 's 18',
|
||||
"'('" => 's 20'
|
||||
),
|
||||
array(
|
||||
"'+'" => 's 2',
|
||||
"'-'" => 's 6',
|
||||
"'*'" => 's 8',
|
||||
"'/'" => 's 10',
|
||||
"'^'" => 's 12',
|
||||
"'%'" => 's 14',
|
||||
"')'" => 's 22'
|
||||
),
|
||||
array(
|
||||
"'%'" => 'r 12',
|
||||
"'^'" => 'r 12',
|
||||
"'/'" => 'r 12',
|
||||
"'*'" => 'r 12',
|
||||
"'-'" => 'r 12',
|
||||
"'+'" => 'r 12',
|
||||
"')'" => 'r 12',
|
||||
'#' => 'r 12'
|
||||
),
|
||||
array(
|
||||
"'='" => 's 24',
|
||||
"'+'" => 'r 3',
|
||||
"'-'" => 'r 3',
|
||||
"'*'" => 'r 3',
|
||||
"'/'" => 'r 3',
|
||||
"'^'" => 'r 3',
|
||||
"'%'" => 'r 3',
|
||||
'#' => 'r 3'
|
||||
),
|
||||
array(
|
||||
'exp' => 's 25',
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
"'+'" => 's 16',
|
||||
"'-'" => 's 18',
|
||||
"'('" => 's 20'
|
||||
),
|
||||
array(
|
||||
"'+'" => 's 2',
|
||||
"'-'" => 's 6',
|
||||
"'*'" => 's 8',
|
||||
"'/'" => 's 10',
|
||||
"'^'" => 's 12',
|
||||
"'%'" => 's 14',
|
||||
'#' => 'r 1'
|
||||
),
|
||||
array(
|
||||
'#' => 'r 13'
|
||||
)
|
||||
);
|
||||
public $d = array(
|
||||
"'+'" => 'plus sign (+)',
|
||||
"'/'" => 'division (/)'
|
||||
);
|
||||
function reduce_0_stmt_1($tokens, &$result) {
|
||||
// (0) stmt := exp
|
||||
$result = reset($tokens);
|
||||
echo " -> "; echo $tokens[0][0] . ' = ' . $tokens[0][1]; echo "\n";
|
||||
}
|
||||
|
||||
function reduce_1_stmt_2($tokens, &$result) {
|
||||
// (1) stmt := var '=' exp
|
||||
$result = reset($tokens);
|
||||
$v = &$tokens[0];
|
||||
$e = &$tokens[2];
|
||||
|
||||
echo "$v = $e\n";
|
||||
set_variable($v, $e);
|
||||
}
|
||||
|
||||
function reduce_2_exp_1($tokens, &$result) {
|
||||
// (2) exp := num
|
||||
$result = reset($tokens);
|
||||
$result = array($tokens[0], $tokens[0]);
|
||||
}
|
||||
|
||||
function reduce_3_exp_2($tokens, &$result) {
|
||||
// (3) exp := var
|
||||
$result = reset($tokens);
|
||||
$result = array($tokens[0], get_variable($tokens[0]));
|
||||
}
|
||||
|
||||
function reduce_4_exp_3($tokens, &$result) {
|
||||
// (4) exp := exp '+' exp
|
||||
$result = reset($tokens);
|
||||
$result = array('(' . $tokens[0][0] . ' + ' . $tokens[2][0] . ')', $tokens[0][1] + $tokens[2][1]);
|
||||
}
|
||||
|
||||
function reduce_5_exp_4($tokens, &$result) {
|
||||
// (5) exp := exp '-' exp
|
||||
$result = reset($tokens);
|
||||
$result = array('(' . $tokens[0][0] . ' - ' . $tokens[2][0] . ')', $tokens[0][1] - $tokens[2][1]);
|
||||
}
|
||||
|
||||
function reduce_6_exp_5($tokens, &$result) {
|
||||
// (6) exp := exp '*' exp
|
||||
$result = reset($tokens);
|
||||
$result = array('(' . $tokens[0][0] . ' * ' . $tokens[2][0] . ')', $tokens[0][1] * $tokens[2][1]);
|
||||
}
|
||||
|
||||
function reduce_7_exp_6($tokens, &$result) {
|
||||
// (7) exp := exp '/' exp
|
||||
$result = reset($tokens);
|
||||
$result = array('(' . $tokens[0][0] . ' / ' . $tokens[2][0] . ')', $tokens[0][1] / $tokens[2][1]);
|
||||
}
|
||||
|
||||
function reduce_8_exp_7($tokens, &$result) {
|
||||
// (8) exp := exp '^' exp
|
||||
$result = reset($tokens);
|
||||
$result = array('(' . $tokens[0][0] . ' ^ ' . $tokens[2][0] . ')', pow($tokens[0][1], $tokens[2][1]));
|
||||
}
|
||||
|
||||
function reduce_9_exp_8($tokens, &$result) {
|
||||
// (9) exp := exp '%' exp
|
||||
$result = reset($tokens);
|
||||
$result = array('(' . $tokens[0][0] . ' % ' . $tokens[2][0] . ')', $tokens[0][1] % $tokens[2][1]);
|
||||
}
|
||||
|
||||
function reduce_10_exp_9($tokens, &$result) {
|
||||
// (10) exp := '+' exp
|
||||
$result = reset($tokens);
|
||||
$result = array('(+ ' . $tokens[1][0] . ')', +($tokens[1][1]));
|
||||
}
|
||||
|
||||
function reduce_11_exp_10($tokens, &$result) {
|
||||
// (11) exp := '-' exp
|
||||
$result = reset($tokens);
|
||||
$result = array('(- ' . $tokens[1][0] . ')', -($tokens[1][1]));
|
||||
}
|
||||
|
||||
function reduce_12_exp_11($tokens, &$result) {
|
||||
// (12) exp := '(' exp ')'
|
||||
$result = $tokens[1];
|
||||
}
|
||||
|
||||
function reduce_13_start_1($tokens, &$result) {
|
||||
// (13) 'start' := stmt
|
||||
$result = reset($tokens);
|
||||
}
|
||||
|
||||
public $method = array(
|
||||
'reduce_0_stmt_1',
|
||||
'reduce_1_stmt_2',
|
||||
'reduce_2_exp_1',
|
||||
'reduce_3_exp_2',
|
||||
'reduce_4_exp_3',
|
||||
'reduce_5_exp_4',
|
||||
'reduce_6_exp_5',
|
||||
'reduce_7_exp_6',
|
||||
'reduce_8_exp_7',
|
||||
'reduce_9_exp_8',
|
||||
'reduce_10_exp_9',
|
||||
'reduce_11_exp_10',
|
||||
'reduce_12_exp_11',
|
||||
'reduce_13_start_1'
|
||||
);
|
||||
public $a = array(
|
||||
array(
|
||||
'symbol' => 'stmt',
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'stmt',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 2,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 2,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => "'start'",
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
)
|
||||
);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
%class calc
|
||||
%start stmt
|
||||
|
||||
%token '+' "plus sign (+)"
|
||||
%token '/' "division (/)"
|
||||
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
%right '^'
|
||||
%right T_INC
|
||||
|
||||
stmt = exp { echo " -> "; echo $1[0] . ' = ' . $1[1]; echo "\n"; }
|
||||
| var/v '=' exp/e {
|
||||
echo "$v = $e\n";
|
||||
set_variable($v, $e);
|
||||
}
|
||||
.
|
||||
|
||||
|
||||
exp = num { $$ = array($1, $1); }
|
||||
| var { $$ = array($1, get_variable($1)); }
|
||||
| exp '+' exp { $$ = array('(' . $1[0] . ' + ' . $3[0] . ')', $1[1] + $3[1]); }
|
||||
| exp '-' exp { $$ = array('(' . $1[0] . ' - ' . $3[0] . ')', $1[1] - $3[1]); }
|
||||
| exp '*' exp { $$ = array('(' . $1[0] . ' * ' . $3[0] . ')', $1[1] * $3[1]); }
|
||||
| exp '/' exp { $$ = array('(' . $1[0] . ' / ' . $3[0] . ')', $1[1] / $3[1]); }
|
||||
| exp '^' exp { $$ = array('(' . $1[0] . ' ^ ' . $3[0] . ')', pow($1[1], $3[1])); }
|
||||
| exp '%' exp { $$ = array('(' . $1[0] . ' % ' . $3[0] . ')', $1[1] % $3[1]); }
|
||||
| '+' exp %prec T_INC { $$ = array('(+ ' . $2[0] . ')', +($2[1])); }
|
||||
| '-' exp %prec T_INC { $$ = array('(- ' . $2[0] . ')', -($2[1])); }
|
||||
| '(' exp/$ ')'
|
||||
.
|
|
@ -0,0 +1,664 @@
|
|||
<?php
|
||||
/*
|
||||
*** DON'T EDIT THIS FILE! ***
|
||||
*
|
||||
* This file was automatically generated by the Lime parser generator.
|
||||
* The real source code you should be looking at is in one or more
|
||||
* grammar files in the Lime format.
|
||||
*
|
||||
* THE ONLY REASON TO LOOK AT THIS FILE is to see where in the grammar
|
||||
* file that your error happened, because there are enough comments to
|
||||
* help you debug your grammar.
|
||||
|
||||
* If you ignore this warning, you're shooting yourself in the brain,
|
||||
* not the foot.
|
||||
*/
|
||||
class calc extends lime_parser {
|
||||
public $qi = 0;
|
||||
public $i = array(
|
||||
array(
|
||||
'exp' => 's 1',
|
||||
'var' => 's 31',
|
||||
'num' => 's 3',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24',
|
||||
'stmt' => 's 34',
|
||||
"'start'" => "a 'start'"
|
||||
),
|
||||
array(
|
||||
"'+'" => 's 2',
|
||||
"'-'" => 's 7',
|
||||
"'*'" => 's 9',
|
||||
"'/'" => 's 11',
|
||||
"'^'" => 's 13',
|
||||
"'%'" => 's 15',
|
||||
'#' => 'r 0'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 30',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 2',
|
||||
"'-'" => 'r 2',
|
||||
"'*'" => 'r 2',
|
||||
"'/'" => 'r 2',
|
||||
"'^'" => 'r 2',
|
||||
"'%'" => 'r 2',
|
||||
"')'" => 'r 2',
|
||||
"','" => 'r 2',
|
||||
'#' => 'r 2'
|
||||
),
|
||||
array(
|
||||
"'('" => 's 5',
|
||||
"'+'" => 'r 3',
|
||||
"'-'" => 'r 3',
|
||||
"'*'" => 'r 3',
|
||||
"'/'" => 'r 3',
|
||||
"'^'" => 'r 3',
|
||||
"'%'" => 'r 3',
|
||||
"')'" => 'r 3',
|
||||
"','" => 'r 3',
|
||||
'#' => 'r 3'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 6',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'param_list' => 's 25',
|
||||
'error' => 's 24',
|
||||
'non_empty_param_list' => 's 27',
|
||||
"')'" => 'r 15'
|
||||
),
|
||||
array(
|
||||
"'+'" => 's 2',
|
||||
"'-'" => 's 7',
|
||||
"'*'" => 's 9',
|
||||
"'/'" => 's 11',
|
||||
"'^'" => 's 13',
|
||||
"'%'" => 's 15',
|
||||
"','" => 'r 17',
|
||||
"')'" => 'r 17'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 8',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 5',
|
||||
"'-'" => 'r 5',
|
||||
"'*'" => 's 9',
|
||||
"'/'" => 's 11',
|
||||
"'^'" => 's 13',
|
||||
"'%'" => 's 15',
|
||||
"')'" => 'r 5',
|
||||
"','" => 'r 5',
|
||||
'#' => 'r 5'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 10',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 6',
|
||||
"'-'" => 'r 6',
|
||||
"'*'" => 'r 6',
|
||||
"'/'" => 'r 6',
|
||||
"'^'" => 's 13',
|
||||
"'%'" => 'r 6',
|
||||
"')'" => 'r 6',
|
||||
"','" => 'r 6',
|
||||
'#' => 'r 6'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 12',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 7',
|
||||
"'-'" => 'r 7',
|
||||
"'*'" => 'r 7',
|
||||
"'/'" => 'r 7',
|
||||
"'^'" => 's 13',
|
||||
"'%'" => 'r 7',
|
||||
"')'" => 'r 7',
|
||||
"','" => 'r 7',
|
||||
'#' => 'r 7'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 14',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 8',
|
||||
"'-'" => 'r 8',
|
||||
"'*'" => 'r 8',
|
||||
"'/'" => 'r 8',
|
||||
"'^'" => 's 13',
|
||||
"'%'" => 'r 8',
|
||||
"')'" => 'r 8',
|
||||
"','" => 'r 8',
|
||||
'#' => 'r 8'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 16',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 9',
|
||||
"'-'" => 'r 9',
|
||||
"'*'" => 'r 9',
|
||||
"'/'" => 'r 9',
|
||||
"'^'" => 's 13',
|
||||
"'%'" => 'r 9',
|
||||
"')'" => 'r 9',
|
||||
"','" => 'r 9',
|
||||
'#' => 'r 9'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 18',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 10',
|
||||
"'-'" => 'r 10',
|
||||
"'*'" => 'r 10',
|
||||
"'/'" => 'r 10',
|
||||
"'^'" => 'r 10',
|
||||
"'%'" => 'r 10',
|
||||
"')'" => 'r 10',
|
||||
"','" => 'r 10',
|
||||
'#' => 'r 10'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 20',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 11',
|
||||
"'-'" => 'r 11',
|
||||
"'*'" => 'r 11',
|
||||
"'/'" => 'r 11',
|
||||
"'^'" => 'r 11',
|
||||
"'%'" => 'r 11',
|
||||
"')'" => 'r 11',
|
||||
"','" => 'r 11',
|
||||
'#' => 'r 11'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 22',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24'
|
||||
),
|
||||
array(
|
||||
"'+'" => 's 2',
|
||||
"'-'" => 's 7',
|
||||
"'*'" => 's 9',
|
||||
"'/'" => 's 11',
|
||||
"'^'" => 's 13',
|
||||
"'%'" => 's 15',
|
||||
"')'" => 's 23'
|
||||
),
|
||||
array(
|
||||
"'%'" => 'r 12',
|
||||
"'^'" => 'r 12',
|
||||
"'/'" => 'r 12',
|
||||
"'*'" => 'r 12',
|
||||
"'-'" => 'r 12',
|
||||
"'+'" => 'r 12',
|
||||
"')'" => 'r 12',
|
||||
"','" => 'r 12',
|
||||
'#' => 'r 12'
|
||||
),
|
||||
array(
|
||||
"'%'" => 'r 14',
|
||||
"'^'" => 'r 14',
|
||||
"'/'" => 'r 14',
|
||||
"'*'" => 'r 14',
|
||||
"'-'" => 'r 14',
|
||||
"'+'" => 'r 14',
|
||||
"')'" => 'r 14',
|
||||
"','" => 'r 14',
|
||||
'#' => 'r 14'
|
||||
),
|
||||
array(
|
||||
"')'" => 's 26'
|
||||
),
|
||||
array(
|
||||
"'%'" => 'r 13',
|
||||
"'^'" => 'r 13',
|
||||
"'/'" => 'r 13',
|
||||
"'*'" => 'r 13',
|
||||
"'-'" => 'r 13',
|
||||
"'+'" => 'r 13',
|
||||
"')'" => 'r 13',
|
||||
"','" => 'r 13',
|
||||
'#' => 'r 13'
|
||||
),
|
||||
array(
|
||||
"','" => 's 28',
|
||||
"')'" => 'r 16'
|
||||
),
|
||||
array(
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
'exp' => 's 29',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24'
|
||||
),
|
||||
array(
|
||||
"'+'" => 's 2',
|
||||
"'-'" => 's 7',
|
||||
"'*'" => 's 9',
|
||||
"'/'" => 's 11',
|
||||
"'^'" => 's 13',
|
||||
"'%'" => 's 15',
|
||||
"','" => 'r 18',
|
||||
"')'" => 'r 18'
|
||||
),
|
||||
array(
|
||||
"'+'" => 'r 4',
|
||||
"'-'" => 'r 4',
|
||||
"'*'" => 's 9',
|
||||
"'/'" => 's 11',
|
||||
"'^'" => 's 13',
|
||||
"'%'" => 's 15',
|
||||
"')'" => 'r 4',
|
||||
"','" => 'r 4',
|
||||
'#' => 'r 4'
|
||||
),
|
||||
array(
|
||||
"'='" => 's 32',
|
||||
"'('" => 's 5',
|
||||
"'+'" => 'r 3',
|
||||
"'-'" => 'r 3',
|
||||
"'*'" => 'r 3',
|
||||
"'/'" => 'r 3',
|
||||
"'^'" => 'r 3',
|
||||
"'%'" => 'r 3',
|
||||
'#' => 'r 3'
|
||||
),
|
||||
array(
|
||||
'exp' => 's 33',
|
||||
'num' => 's 3',
|
||||
'var' => 's 4',
|
||||
"'+'" => 's 17',
|
||||
"'-'" => 's 19',
|
||||
"'('" => 's 21',
|
||||
'error' => 's 24'
|
||||
),
|
||||
array(
|
||||
"'+'" => 's 2',
|
||||
"'-'" => 's 7',
|
||||
"'*'" => 's 9',
|
||||
"'/'" => 's 11',
|
||||
"'^'" => 's 13',
|
||||
"'%'" => 's 15',
|
||||
'#' => 'r 1'
|
||||
),
|
||||
array(
|
||||
'#' => 'r 19'
|
||||
)
|
||||
);
|
||||
public $d = array(
|
||||
"'+'" => 'plus operator (+)',
|
||||
"'-'" => 'minus operator (-)',
|
||||
"'*'" => 'multiplication operator (*)',
|
||||
"'/'" => 'division operator (/)',
|
||||
"'%'" => 'modulo operator (%)',
|
||||
"'^'" => 'exponentiation operator (^)'
|
||||
);
|
||||
function reduce_0_stmt_1($tokens, &$result) {
|
||||
// (0) stmt := exp
|
||||
$result = reset($tokens);
|
||||
|
||||
echo ' -> ';
|
||||
echo $tokens[0][0] . ' = ' . $tokens[0][1];
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
function reduce_1_stmt_2($tokens, &$result) {
|
||||
// (1) stmt := var '=' exp
|
||||
$result = reset($tokens);
|
||||
$v = &$tokens[0];
|
||||
$e = &$tokens[2];
|
||||
|
||||
echo $v . ' = ' . $e . "\n";
|
||||
set_variable($v, $e);
|
||||
}
|
||||
|
||||
function reduce_2_exp_1($tokens, &$result) {
|
||||
// (2) exp := num
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array($tokens[0], $tokens[0]);
|
||||
}
|
||||
|
||||
function reduce_3_exp_2($tokens, &$result) {
|
||||
// (3) exp := var
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array($tokens[0], get_variable($tokens[0]));
|
||||
}
|
||||
|
||||
function reduce_4_exp_3($tokens, &$result) {
|
||||
// (4) exp := exp '+' exp
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array(
|
||||
'(' . $tokens[0][0] . ' + ' . $tokens[2][0] . ')',
|
||||
nan_or($tokens[0][1], $tokens[2][1], $tokens[0][1] + $tokens[2][1])
|
||||
);
|
||||
}
|
||||
|
||||
function reduce_5_exp_4($tokens, &$result) {
|
||||
// (5) exp := exp '-' exp
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array(
|
||||
'(' . $tokens[0][0] . ' - ' . $tokens[2][0] . ')',
|
||||
nan_or($tokens[0][1], $tokens[2][1], $tokens[0][1] - $tokens[2][1])
|
||||
);
|
||||
}
|
||||
|
||||
function reduce_6_exp_5($tokens, &$result) {
|
||||
// (6) exp := exp '*' exp
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array(
|
||||
'(' . $tokens[0][0] . ' * ' . $tokens[2][0] . ')',
|
||||
nan_or($tokens[0][1], $tokens[2][1], $tokens[0][1] * $tokens[2][1])
|
||||
);
|
||||
}
|
||||
|
||||
function reduce_7_exp_6($tokens, &$result) {
|
||||
// (7) exp := exp '/' exp
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array(
|
||||
'(' . $tokens[0][0] . ' / ' . $tokens[2][0] . ')',
|
||||
nan_or($tokens[0][1], $tokens[2][1], $tokens[0][1] / $tokens[2][1])
|
||||
);
|
||||
}
|
||||
|
||||
function reduce_8_exp_7($tokens, &$result) {
|
||||
// (8) exp := exp '^' exp
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array(
|
||||
'(' . $tokens[0][0] . ' ^ ' . $tokens[2][0] . ')',
|
||||
nan_or($tokens[0][1], $tokens[2][1], pow($tokens[0][1], $tokens[2][1]))
|
||||
);
|
||||
}
|
||||
|
||||
function reduce_9_exp_8($tokens, &$result) {
|
||||
// (9) exp := exp '%' exp
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array(
|
||||
'(' . $tokens[0][0] . ' % ' . $tokens[2][0] . ')',
|
||||
nan_or($tokens[0][1], $tokens[2][1], $tokens[0][1] % $tokens[2][1])
|
||||
);
|
||||
}
|
||||
|
||||
function reduce_10_exp_9($tokens, &$result) {
|
||||
// (10) exp := '+' exp
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array(
|
||||
'(+ ' . $tokens[1][0] . ')',
|
||||
nan_or($tokens[0][1], $tokens[2][1], +($tokens[1][1]))
|
||||
);
|
||||
}
|
||||
|
||||
function reduce_11_exp_10($tokens, &$result) {
|
||||
// (11) exp := '-' exp
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array(
|
||||
'(- ' . $tokens[1][0] . ')',
|
||||
nan_or($tokens[0][1], $tokens[2][1], -($tokens[1][1]))
|
||||
);
|
||||
}
|
||||
|
||||
function reduce_12_exp_11($tokens, &$result) {
|
||||
// (12) exp := '(' exp ')'
|
||||
$result = $tokens[1];
|
||||
}
|
||||
|
||||
function reduce_13_exp_12($tokens, &$result) {
|
||||
// (13) exp := var '(' param_list ')'
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array(
|
||||
// little bits of voodoo to make this happen
|
||||
'(' . $tokens[0] . '(' .
|
||||
implode(', ', array_map(function ($a) {
|
||||
return $a[0];
|
||||
}, $tokens[2])) .
|
||||
'))',
|
||||
call_user_func_array($tokens[0], array_map(function ($a) {
|
||||
return $a[1];
|
||||
}, $tokens[2]))
|
||||
);
|
||||
}
|
||||
|
||||
function reduce_14_exp_13($tokens, &$result) {
|
||||
// (14) exp := error
|
||||
$result = reset($tokens);
|
||||
|
||||
printf("Error\n");
|
||||
$result = array('NaN', NaN);
|
||||
}
|
||||
|
||||
function reduce_15_param_list_1($tokens, &$result) {
|
||||
// (15) param_list :=
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array();
|
||||
}
|
||||
|
||||
function reduce_16_param_list_2($tokens, &$result) {
|
||||
// (16) param_list := non_empty_param_list
|
||||
$result = reset($tokens);
|
||||
}
|
||||
|
||||
function reduce_17_non_empty_param_list_1($tokens, &$result) {
|
||||
// (17) non_empty_param_list := exp
|
||||
$result = reset($tokens);
|
||||
|
||||
$result = array($tokens[0]);
|
||||
}
|
||||
|
||||
function reduce_18_non_empty_param_list_2($tokens, &$result) {
|
||||
// (18) non_empty_param_list := non_empty_param_list ',' exp
|
||||
$result = reset($tokens);
|
||||
|
||||
$tokens[0][] = $tokens[2];
|
||||
$result = $tokens[0];
|
||||
}
|
||||
|
||||
function reduce_19_start_1($tokens, &$result) {
|
||||
// (19) 'start' := stmt
|
||||
$result = reset($tokens);
|
||||
}
|
||||
|
||||
public $method = array(
|
||||
'reduce_0_stmt_1',
|
||||
'reduce_1_stmt_2',
|
||||
'reduce_2_exp_1',
|
||||
'reduce_3_exp_2',
|
||||
'reduce_4_exp_3',
|
||||
'reduce_5_exp_4',
|
||||
'reduce_6_exp_5',
|
||||
'reduce_7_exp_6',
|
||||
'reduce_8_exp_7',
|
||||
'reduce_9_exp_8',
|
||||
'reduce_10_exp_9',
|
||||
'reduce_11_exp_10',
|
||||
'reduce_12_exp_11',
|
||||
'reduce_13_exp_12',
|
||||
'reduce_14_exp_13',
|
||||
'reduce_15_param_list_1',
|
||||
'reduce_16_param_list_2',
|
||||
'reduce_17_non_empty_param_list_1',
|
||||
'reduce_18_non_empty_param_list_2',
|
||||
'reduce_19_start_1'
|
||||
);
|
||||
public $a = array(
|
||||
array(
|
||||
'symbol' => 'stmt',
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'stmt',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 2,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 2,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 4,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'exp',
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'param_list',
|
||||
'len' => 0,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'param_list',
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'non_empty_param_list',
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'non_empty_param_list',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => "'start'",
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Time: 0.12659001350403 seconds
|
||||
// Memory: 2765212 bytes
|
|
@ -0,0 +1,117 @@
|
|||
%class calc
|
||||
%start stmt
|
||||
|
||||
%token '+' "plus operator (+)"
|
||||
%token '-' "minus operator (-)"
|
||||
%token '*' "multiplication operator (*)"
|
||||
%token '/' "division operator (/)"
|
||||
%token '%' "modulo operator (%)"
|
||||
%token '^' "exponentiation operator (^)"
|
||||
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
%right '^'
|
||||
%right T_INC
|
||||
|
||||
stmt = exp {
|
||||
echo ' -> ';
|
||||
echo $1[0] . ' = ' . $1[1];
|
||||
echo "\n";
|
||||
}
|
||||
| var/v '=' exp/e {
|
||||
echo $v . ' = ' . $e . "\n";
|
||||
set_variable($v, $e);
|
||||
}
|
||||
.
|
||||
|
||||
|
||||
exp = num {
|
||||
$$ = array($1, $1);
|
||||
}
|
||||
| var {
|
||||
$$ = array($1, get_variable($1));
|
||||
}
|
||||
| exp '+' exp {
|
||||
$$ = array(
|
||||
'(' . $1[0] . ' + ' . $3[0] . ')',
|
||||
nan_or($1[1], $3[1], $1[1] + $3[1])
|
||||
);
|
||||
}
|
||||
| exp '-' exp {
|
||||
$$ = array(
|
||||
'(' . $1[0] . ' - ' . $3[0] . ')',
|
||||
nan_or($1[1], $3[1], $1[1] - $3[1])
|
||||
);
|
||||
}
|
||||
| exp '*' exp {
|
||||
$$ = array(
|
||||
'(' . $1[0] . ' * ' . $3[0] . ')',
|
||||
nan_or($1[1], $3[1], $1[1] * $3[1])
|
||||
);
|
||||
}
|
||||
| exp '/' exp {
|
||||
$$ = array(
|
||||
'(' . $1[0] . ' / ' . $3[0] . ')',
|
||||
nan_or($1[1], $3[1], $1[1] / $3[1])
|
||||
);
|
||||
}
|
||||
| exp '^' exp {
|
||||
$$ = array(
|
||||
'(' . $1[0] . ' ^ ' . $3[0] . ')',
|
||||
nan_or($1[1], $3[1], pow($1[1], $3[1]))
|
||||
);
|
||||
}
|
||||
| exp '%' exp {
|
||||
$$ = array(
|
||||
'(' . $1[0] . ' % ' . $3[0] . ')',
|
||||
nan_or($1[1], $3[1], $1[1] % $3[1])
|
||||
);
|
||||
}
|
||||
| '+' exp %prec T_INC {
|
||||
$$ = array(
|
||||
'(+ ' . $2[0] . ')',
|
||||
nan_or($1[1], $3[1], +($2[1]))
|
||||
);
|
||||
}
|
||||
| '-' exp %prec T_INC {
|
||||
$$ = array(
|
||||
'(- ' . $2[0] . ')',
|
||||
nan_or($1[1], $3[1], -($2[1]))
|
||||
);
|
||||
}
|
||||
| '(' exp/$ ')'
|
||||
| var '(' param_list ')' {
|
||||
$$ = array(
|
||||
// little bits of voodoo to make this happen
|
||||
'(' . $1 . '(' .
|
||||
implode(', ', array_map(function ($a) {
|
||||
return $a[0];
|
||||
}, $3)) .
|
||||
'))',
|
||||
call_user_func_array($1, array_map(function ($a) {
|
||||
return $a[1];
|
||||
}, $3))
|
||||
);
|
||||
}
|
||||
| error {
|
||||
printf("Error\n");
|
||||
$$ = array('NaN', NaN);
|
||||
}
|
||||
.
|
||||
|
||||
param_list:
|
||||
/* empty */ {
|
||||
$$ = array();
|
||||
}
|
||||
| non_empty_param_list
|
||||
.
|
||||
|
||||
non_empty_param_list:
|
||||
exp {
|
||||
$$ = array($1);
|
||||
}
|
||||
| non_empty_param_list ',' exp {
|
||||
$1[] = $3;
|
||||
$$ = $1;
|
||||
}
|
||||
.
|
|
@ -6,10 +6,12 @@ and use it in another calculation like:
|
|||
|
||||
<?
|
||||
|
||||
include_once "../parse_engine.php";
|
||||
include_once "../../parse_engine.php";
|
||||
include_once "calc.class";
|
||||
|
||||
|
||||
function nan_or($l, $r, $or) {
|
||||
return !is_numeric($l) || !is_numeric($r) || is_nan($l) || is_nan($r) ? NaN : $or;
|
||||
}
|
||||
|
||||
function tokenize($line) {
|
||||
// Numbers are tokens, as are all other non-whitespace characters.
|
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
/*
|
||||
*** DON'T EDIT THIS FILE! ***
|
||||
*
|
||||
* This file was automatically generated by the Lime parser generator.
|
||||
* The real source code you should be looking at is in one or more
|
||||
* grammar files in the Lime format.
|
||||
*
|
||||
* THE ONLY REASON TO LOOK AT THIS FILE is to see where in the grammar
|
||||
* file that your error happened, because there are enough comments to
|
||||
* help you debug your grammar.
|
||||
|
||||
* If you ignore this warning, you're shooting yourself in the brain,
|
||||
* not the foot.
|
||||
*/
|
||||
class parser extends lime_parser {
|
||||
public $qi = 0;
|
||||
public $i = array(
|
||||
array(
|
||||
'slist' => 's 1',
|
||||
'stmt' => 's 6',
|
||||
'error' => 's 8',
|
||||
'ZZ' => 's 4',
|
||||
"'start'" => "a 'start'"
|
||||
),
|
||||
array(
|
||||
'stmt' => 's 2',
|
||||
'ZZ' => 's 4',
|
||||
'#' => 'r 5'
|
||||
),
|
||||
array(
|
||||
"';'" => 's 3'
|
||||
),
|
||||
array(
|
||||
'ZZ' => 'r 0',
|
||||
'#' => 'r 0'
|
||||
),
|
||||
array(
|
||||
'ZZ' => 's 4',
|
||||
'stmt' => 's 5',
|
||||
"';'" => 'r 4'
|
||||
),
|
||||
array(
|
||||
"';'" => 'r 3'
|
||||
),
|
||||
array(
|
||||
"';'" => 's 7'
|
||||
),
|
||||
array(
|
||||
'ZZ' => 'r 1',
|
||||
'#' => 'r 1'
|
||||
),
|
||||
array(
|
||||
"';'" => 's 9'
|
||||
),
|
||||
array(
|
||||
'ZZ' => 'r 2',
|
||||
'#' => 'r 2'
|
||||
)
|
||||
);
|
||||
public $d = array(
|
||||
|
||||
);
|
||||
function reduce_0_slist_1($tokens, &$result) {
|
||||
// (0) slist := slist stmt ';'
|
||||
$result = reset($tokens);
|
||||
|
||||
printf("slist stmt\n");
|
||||
$result = array($tokens[0], $tokens[1]);
|
||||
}
|
||||
|
||||
function reduce_1_slist_2($tokens, &$result) {
|
||||
// (1) slist := stmt ';'
|
||||
$result = reset($tokens);
|
||||
|
||||
printf("stmt\n");
|
||||
$result = $tokens[0];
|
||||
}
|
||||
|
||||
function reduce_2_slist_3($tokens, &$result) {
|
||||
// (2) slist := error ';'
|
||||
$result = reset($tokens);
|
||||
|
||||
printf("error\n");
|
||||
$result = 'error';
|
||||
}
|
||||
|
||||
function reduce_3_stmt_1($tokens, &$result) {
|
||||
// (3) stmt := ZZ stmt
|
||||
$result = reset($tokens);
|
||||
|
||||
printf("ZZ stmt\n");
|
||||
$result = array($tokens[0], $tokens[1]);
|
||||
}
|
||||
|
||||
function reduce_4_stmt_2($tokens, &$result) {
|
||||
// (4) stmt := ZZ
|
||||
$result = reset($tokens);
|
||||
|
||||
printf("ZZ\n");
|
||||
$result = array($tokens[0]);
|
||||
}
|
||||
|
||||
function reduce_5_start_1($tokens, &$result) {
|
||||
// (5) 'start' := slist
|
||||
$result = reset($tokens);
|
||||
}
|
||||
|
||||
public $method = array(
|
||||
'reduce_0_slist_1',
|
||||
'reduce_1_slist_2',
|
||||
'reduce_2_slist_3',
|
||||
'reduce_3_stmt_1',
|
||||
'reduce_4_stmt_2',
|
||||
'reduce_5_start_1'
|
||||
);
|
||||
public $a = array(
|
||||
array(
|
||||
'symbol' => 'slist',
|
||||
'len' => 3,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'slist',
|
||||
'len' => 2,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'slist',
|
||||
'len' => 2,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'stmt',
|
||||
'len' => 2,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => 'stmt',
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
),
|
||||
array(
|
||||
'symbol' => "'start'",
|
||||
'len' => 1,
|
||||
'replace' => true
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Time: 0.039383888244629 seconds
|
||||
// Memory: 1514364 bytes
|
|
@ -0,0 +1,27 @@
|
|||
#program: slist { var_dump($1); $$ = $1; };
|
||||
|
||||
slist:
|
||||
slist stmt ';' {
|
||||
printf("slist stmt\n");
|
||||
$$ = array($1, $2);
|
||||
}
|
||||
| stmt ';' {
|
||||
printf("stmt\n");
|
||||
$$ = $1;
|
||||
}
|
||||
| error ';' {
|
||||
printf("error\n");
|
||||
$$ = 'error';
|
||||
}
|
||||
;
|
||||
|
||||
stmt:
|
||||
ZZ stmt {
|
||||
printf("ZZ stmt\n");
|
||||
$$ = array($1, $2);
|
||||
}
|
||||
| ZZ {
|
||||
printf("ZZ\n");
|
||||
$$ = array($1);
|
||||
}
|
||||
;
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
include_once "../../parse_engine.php";
|
||||
include_once "error.class";
|
||||
|
||||
$parser = new parse_engine(new parser());
|
||||
//$parser->debug = true;
|
||||
|
||||
$tokens = array(
|
||||
array('ZZ', 'zz'),
|
||||
array('ZZ', 'zz'),
|
||||
array('YY', 'yy'),
|
||||
';',
|
||||
array('ZZ', 'zz'),
|
||||
array('ZZ', 'zz'),
|
||||
';'
|
||||
);
|
||||
|
||||
foreach($tokens as $token) {
|
||||
if (is_array($token)) {
|
||||
$parser->eat($token[0], $token[1]);
|
||||
} else {
|
||||
$parser->eat("'{$token}'", $token);
|
||||
}
|
||||
}
|
||||
|
||||
$parser->eat_eof();
|
||||
|
||||
var_dump($parser->semantic);
|
||||
var_dump($parser->errors);
|
2
lime.php
2
lime.php
|
@ -470,7 +470,7 @@ class rule {
|
|||
$symbol_after_the_dot = $this->rhs[$dot];
|
||||
$first = $symbol_after_the_dot->first->all();
|
||||
|
||||
bug_if(empty($first) and !$symbol_after_the_dot->lambda);
|
||||
bug_if(empty($first) and !$symbol_after_the_dot->lambda and $symbol_after_the_dot->name != 'error');
|
||||
|
||||
$set = new set($first);
|
||||
if ($symbol_after_the_dot->lambda) {
|
||||
|
|
|
@ -102,11 +102,14 @@ class parse_stack {
|
|||
}
|
||||
|
||||
class parse_engine {
|
||||
public $debug = false;
|
||||
|
||||
public $parser;
|
||||
public $qi;
|
||||
public $rule;
|
||||
public $step;
|
||||
public $descr;
|
||||
public $errors = array();
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
|
@ -129,6 +132,7 @@ class parse_engine {
|
|||
public function reset() {
|
||||
$this->accept = false;
|
||||
$this->stack = new parse_stack($this->qi);
|
||||
$this->errors = array();
|
||||
}
|
||||
|
||||
private function enter_error_tolerant_state() {
|
||||
|
@ -137,6 +141,9 @@ class parse_engine {
|
|||
return true;
|
||||
}
|
||||
|
||||
if ($this->debug) echo "Dropped an item from the stack, {" . implode(', ', $this->get_steps()) . "} left\n";
|
||||
if ($this->debug) echo 'Currently in state ' . $this->state() . "\n";
|
||||
|
||||
$this->drop();
|
||||
}
|
||||
|
||||
|
@ -225,7 +232,7 @@ class parse_engine {
|
|||
|
||||
$expect = $this->get_steps();
|
||||
|
||||
while ($this->enter_error_tolerant_state()) {
|
||||
while ($this->enter_error_tolerant_state() || $this->has_step_for('error')) {
|
||||
if (isset($seen[$this->state()])) {
|
||||
// This means that it's pointless to try here.
|
||||
// We're guaranteed that the stack is occupied.
|
||||
|
@ -235,7 +242,7 @@ class parse_engine {
|
|||
|
||||
$seen[$this->state()] = true;
|
||||
|
||||
$this->eat('error', null);
|
||||
$this->eat('error', 'Premature EOF');
|
||||
|
||||
if ($this->has_step_for('#')) {
|
||||
// Good. We can continue as normal.
|
||||
|
@ -293,16 +300,17 @@ class parse_engine {
|
|||
|
||||
function eat($type, $semantic) {
|
||||
// assert('$type == trim($type)');
|
||||
// if ($this->debug) echo "Trying to eat a ($type)\n";
|
||||
if ($this->debug) echo "Trying to eat a ($type)\n";
|
||||
list($opcode, $operand) = $this->step_for($type);
|
||||
|
||||
switch ($opcode) {
|
||||
case 's':
|
||||
// if ($this->debug) echo "shift $type to state $operand\n";
|
||||
if ($this->debug) echo "shift $type to state $operand\n";
|
||||
$this->stack->shift($operand, $semantic);
|
||||
// echo $this->stack->text()." shift $type<br/>\n";
|
||||
break;
|
||||
case 'r':
|
||||
if ($this->debug) echo "Reducing $type via rule $operand\n";
|
||||
$this->reduce($operand);
|
||||
$this->eat($type, $semantic);
|
||||
// Yes, this is tail-recursive. It's also the simplest way.
|
||||
|
@ -313,20 +321,24 @@ class parse_engine {
|
|||
}
|
||||
|
||||
$this->accept = true;
|
||||
//if ($this->debug) echo ("Accept\n\n");
|
||||
if ($this->debug) echo ("Accept\n\n");
|
||||
$this->semantic = $semantic;
|
||||
break;
|
||||
case 'e':
|
||||
// This is thought to be the uncommon, exceptional path, so
|
||||
// it's OK that this algorithm will cause the stack to
|
||||
// flutter while the parse engine waits for an edible token.
|
||||
// if ($this->debug) echo "($type) causes a problem.\n";
|
||||
if ($this->debug) echo "($type) causes a problem.\n";
|
||||
|
||||
// get these before doing anything
|
||||
$expected = $this->get_steps();
|
||||
|
||||
if ($this->enter_error_tolerant_state()) {
|
||||
$this->eat('error', null);
|
||||
$this->errors[] = $this->descr($type, $semantic) . ' not expected, expected {' . implode(', ', $expected) . '}';
|
||||
|
||||
if ($this->debug) echo "Possibilities before error fixing: {" . implode(', ', $expected) . "}\n";
|
||||
|
||||
if ($this->enter_error_tolerant_state() || $this->has_step_for('error')) {
|
||||
$this->eat('error', end($this->errors));
|
||||
if ($this->has_step_for($type)) {
|
||||
$this->eat($type, $semantic);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue