PHP PEG.js
** This repo is not maintained for a while please use phpegjs module instead **
PHP PEG.js is a php code generation plugin for PEG.js.
Requirements
Installation
Node.js
Install PEG.js with php-pegjs plugin
$ npm install php-pegjs
Usage
Generating a Parser
In Node.js, require both the PEG.js parser generator and the php-pegjs plugin:
var pegjs = require("pegjs");
var phppegjs = require("php-pegjs");
To generate a php parser, pass to pegjs.buildParser
php-pegjs plugin and your grammar:
var parser = pegjs.buildParser("start = ('a' / 'b')+", {
plugins: [phppegjs]
});
The method will return source code of generated parser as a string. Unlike original PEG.js, generated php parser will be a class, not a function.
Supported options of pegjs.buildParser
:
cache
— iftrue
, makes the parser cache results, avoiding exponential parsing time in pathological cases but making the parser slower (default:false
). In case of php, this is strongly recommended for big grammars (like javascript.pegjs or css.pegjs in example folder)allowedStartRules
— rules the parser will be allowed to start parsing from (default: the first rule in the grammar)
Additional PHP PEG.js plugin options:
phppegjs.parserNamespace
- namespace of generated parser (default:"PhpPegJs"
). If value is""
, parser will be in global namespacephppegjs.parserClassName
- name of generated class for parser (default:"Parser"
)
Using the Parser
-
Save parser generated by
pegjs.buildParser
to a file -
In php code:
include "your.parser.file.php";
try { $parser = new PhpPegJs\Parser; $result = $parser->parse($input); } catch (PhpPegJs\SyntaxError $ex) { // Handle parsing error // [...] }
You can use following snippet to format parsing error:
catch (PhpPegJs\SyntaxError $ex)
{
$message = "Syntax error: " . $ex->getMessage() . ' At line ' . $ex->grammarLine . ' column ' . $ex->grammarColumn . ' offset ' . $ex->grammarOffset;
}
Grammar Syntax and Semantics
See documentation of PEG.js with one difference: action blocks should be written on PHP.
Original PEG.js rule:
media_list
= head:medium tail:("," S* medium)* {
var result = [head];
for (var i = 0; i < tail.length; i++) {
result.push(tail[i][2]);
}
return result;
}
PHP PEG.js rule:
media_list
= head:medium tail:("," S* medium)* {
$result = array($head);
for ($i = 0; $i < count($tail); $i++) {
$result[] = $tail[$i][2];
}
return $result;
}
You can also use following util functions in action blocks:
chr_unicode($code)
- return character by its UTF-8 code (Analogue of javascript String.fromCharCode)
Guide of converting PEG.js action blocks to PHP PEG.js
Javascript code | PHP analogue |
---|---|
some_var |
$some_var |
{f1: "val1", f2: "val2"} |
array("f1" => "val1", "f2" => "val2") |
["val1", "val2"] |
array("val1", "val2") |
some_array.push("val") |
$some_array[] = "val" |
some_array.length |
count($some_array) |
some_array.join("") |
join("", $some_array) |
some_array1.concat(some_array2) |
array_merge($some_array1, $some_array2) |
parseInt("23") |
intval("23") |
parseFloat("23.1") |
floatval("23.1") |
some_str.length |
mb_strlen(some_str, "UTF-8") |
some_str.replace("b", "\b") |
str_replace("b", "\b", $some_str) |
String.fromCharCode(2323) |
chr_unicode(2323) |
text() |
$this->text() |
location() |
$this->location() |
Function $this->location()
returns object with following structure:
{
'start' => {
'offset' => int,
'line' => int,
'column' => int,
},
'end' => {
'offset' => int,
'line' => int,
'column' => int,
},
}