Skip to content

Commit 3085404

Browse files
committed
Added ParsingException. Renamed Conveyor::readClassname to readName
1 parent 42916fa commit 3085404

File tree

6 files changed

+124
-11
lines changed

6 files changed

+124
-11
lines changed

app/Exception/ParsingException.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
/* MIT License
4+
5+
Copyright (c) 2018 Eridan Domoratskiy
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE. */
24+
25+
namespace PHPDataGen\Exception;
26+
27+
/**
28+
* Parsing exception
29+
*/
30+
class ParsingException extends \Exception {
31+
32+
/**
33+
* @var string Description of caused exception
34+
*/
35+
protected $description = null;
36+
37+
/**
38+
* @var string Line that caused exception
39+
*/
40+
protected $line = 0;
41+
42+
/**
43+
* @var int Column number of line that caused exception
44+
*/
45+
protected $column = 0;
46+
47+
/**
48+
* @var int Row number of line that caused exception
49+
*/
50+
protected $row = 0;
51+
52+
/**
53+
* @param string $description Description of caused exception
54+
* @param string $line Line that caused exception
55+
* @param int $row Row number of line that caused exception
56+
* @param int $column Column number of line that caused exception
57+
* @param int $code Exception code
58+
* @param \Throwable $previous Previous exception
59+
*/
60+
public function __construct(
61+
string $description,
62+
string $line,
63+
int $row,
64+
int $column,
65+
int $code = 0,
66+
\Throwable $previous = null
67+
) {
68+
$this->description = $description;
69+
$this->line = $line;
70+
71+
$this->column = $column;
72+
$this->row = $row;
73+
74+
$msg = "$description at row $row, column $column:\n$line\n";
75+
for ($i = 0; $i < $column; ++$i) {
76+
$msg .= ' ';
77+
}
78+
$msg .= '^';
79+
80+
parent::__construct($msg, $code, $previous);
81+
}
82+
}

app/Parsing/ClassState.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public function getBuilder(): ClassBuilder {
7575
public function step(Conveyor $conveyor): State {
7676
switch ($this->state) {
7777
case 0:
78-
$this->builder->setName($conveyor->readClassname());
78+
$this->builder->setName($conveyor->readName());
7979

8080
$this->state = 1;
8181
return $this;

app/Parsing/Conveyor.php

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,18 @@
2424

2525
namespace PHPDataGen\Parsing;
2626

27+
use PHPDataGen\Exception\ParsingException;
28+
2729
/**
2830
* Parsing conveyor
2931
*/
3032
class Conveyor {
3133

34+
/**
35+
* @var string Source string
36+
*/
37+
protected $source = null;
38+
3239
/**
3340
* @var string Next string
3441
*/
@@ -53,7 +60,9 @@ class Conveyor {
5360
* @param string $source Source of conveyor
5461
*/
5562
public function __construct(string $source) {
63+
$this->source = $source;
5664
$this->next = $source;
65+
5766
$this->length = strlen($source);
5867
}
5968

@@ -66,6 +75,23 @@ public function length(): int {
6675
return $this->length;
6776
}
6877

78+
public function makeException(string $description, int $code = 0, \Throwable $previous): ParsingException {
79+
$offset = strlen($this->source) - $this->length;
80+
81+
for (; $offset > 0; --$offset) {
82+
// TODO Configurable newline symbol
83+
if ($this->source[$offset] === '\n') {
84+
break;
85+
}
86+
}
87+
++$offset;
88+
89+
$line = substr($this->source, $offset);
90+
$line = substr($line, 0, strpos($line, "\n"));
91+
92+
return new ParsingException($description, $line, $this->row, $this->column, $code, $previous);
93+
}
94+
6995
/**
7096
* Moves conveyor on specified offset.
7197
* Offset must be pozitive (or null)
@@ -110,8 +136,7 @@ public function readOperator(string $operator, bool $skip = true, bool $required
110136
}
111137

112138
if ($required) {
113-
// TODO Parsing exception class
114-
throw new \Exception("$operator not found at {$this->line} line {$this->row} row");
139+
throw $this->makeException("\"$operator\" expected");
115140
}
116141

117142
return false;
@@ -152,7 +177,7 @@ public function readNamespace(): string {
152177
return $matches[0];
153178
}
154179

155-
throw new \Exception('Namespace not found');
180+
throw $this->makeException("Namespace expected");
156181
}
157182

158183
/**
@@ -161,14 +186,14 @@ public function readNamespace(): string {
161186
*
162187
* @return string Class name
163188
*/
164-
public function readClassname(): string {
189+
public function readName(): string {
165190
if (preg_match('/^[a-z_]\\w*/i', $this->next, $matches) === 1) {
166191
$this->move(strlen($matches[0]));
167192

168193
return $matches[0];
169194
}
170195

171-
throw new \Exception('Class name not found');
196+
throw $this->makeException("Name expected");
172197
}
173198

174199
/**
@@ -184,7 +209,11 @@ public function readExtendedClassname(): string {
184209
return $matches[0];
185210
}
186211

187-
return $this->readClassname();
212+
try {
213+
return $this->readName();
214+
} catch (ParseException $e) {
215+
throw $this->makeException("Class name expected", 0, $e);
216+
}
188217
}
189218

190219
/**
@@ -196,7 +225,7 @@ public function readSemicolon() {
196225
return;
197226
}
198227

199-
throw new \Exception('Semicolon not found');
228+
throw $this->makeException("Semicolon expected");
200229
}
201230

202231
public function __toString() {

app/Parsing/FieldState.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public function step(Conveyor $conveyor): State {
9696
throw new \Exception('Expected val/var operator');
9797

9898
case 2:
99-
$this->builder->setName($conveyor->readClassname());
99+
$this->builder->setName($conveyor->readName());
100100

101101
$this->state = 3;
102102
return $this;
@@ -140,7 +140,7 @@ public function step(Conveyor $conveyor): State {
140140
return $this;
141141

142142
case 6:
143-
$this->builder->addValidator($conveyor->readClassname());
143+
$this->builder->addValidator($conveyor->readName());
144144

145145
$this->state = 5;
146146
return $this;

app/Parsing/FileState.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public function step(Conveyor $conveyor): State {
111111
return $this;
112112

113113
case 4:
114-
$this->builder->addUse($this->useBuffer, $conveyor->readClassname());
114+
$this->builder->addUse($this->useBuffer, $conveyor->readName());
115115
$this->useBuffer = null;
116116

117117
$this->state = 5;

php-datagen

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ if (file_exists(__DIR__.'/../../autoload.php')) {
88
}
99

1010
$app = new Symfony\Component\Console\Application('PHP-DataGen', '0.2-alpha');
11+
12+
// TODO Build, config commands
1113
// $app->add(new PHPDataGen\Commands\);
1214

1315
$app->run();

0 commit comments

Comments
 (0)