-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSJMForm.regex.php
More file actions
71 lines (64 loc) · 1.85 KB
/
Copy pathSJMForm.regex.php
File metadata and controls
71 lines (64 loc) · 1.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?php
/**
* Simple regex parser as described in http://heap.ch/blog/2015/12/25/sjmform/
*/
class SJMFormRegex {
private $literals = array();
public function __construct() {
$this->literals['true'] = true;
$this->literals['false'] = false;
$this->literals['null'] = null;
}
public function parse($fml) {
$fml = $this->stringExtract($fml);
$ast = $this->parseAtom($fml);
return $ast;
}
// form markup language parse functions
private function parseAtom($fml) {
$pattern = '/(\w+)\s+(\w+)\s*\((.*?)\)\s*(\{(.*?)\}\s*)?;/s';
$offset = 0;
$tree = array();
while (preg_match($pattern, $fml, $m, PREG_OFFSET_CAPTURE, $offset)===1) {
$node = new stdClass();
$node->type = $m[1][0];
$node->name = $m[2][0];
$node->args = $this->arglist($m[3][0]);
if (isset($m[5])) $node->childNodes = $this->parseAtom($m[5][0]);
$offset = $m[0][1] + strlen($m[0][0]);
$tree []= $node;
}
return $tree;
}
private function arglist($argstring) {
// replace placeholders with actual value
$args = array();
foreach (explode(',', $argstring) as $arg) {
$literal = trim($arg);
if (array_key_exists($literal, $this->literals)) {
$args []= $this->literals[$literal];
} elseif (is_numeric($literal)) {
$args []= $literal + 0; // int or float
} else {
die ("invalid literal: $literal");
}
}
return $args;
}
private function stringExtract($fml) {
// remove comments (lines starting with #)
$fml = preg_replace('/^\s*#.*$/m', '', $fml);
// replace string literals with place holders
$pattern = '/"(.*?)(?<!\\\\)"/';
return preg_replace_callback($pattern, array($this, 'stringReplace'), $fml);
}
private function stringReplace($matches) {
static $n = 1;
// remove escape chars
$string = str_replace('\\"', '"', $matches[1]);
$key = "str$n";
$n += 1;
$this->literals[$key] = $string;
return $key;
}
}