
# Parser

Phasis tillhandahåller sin JavaScript-parser som ett fristående PHP API. Du kan parsa källtext till en typad AST, traversera den och exportera den som ESTree-formade arrayer eller JSON utan att skapa en `Engine` eller köra något.

## parseSource

```php
public static function parseSource(string $source, string $sourceType = 'script'): Program
```

Ingångspunkten med ett enda anrop på `Phasis\Parser\Parser`. Parsar `$source` och returnerar rotnoden `Phasis\Ast\Program`.

```php
use Phasis\Parser\Parser;

$program = Parser::parseSource('const x = [1, 2].map(n => n * 2);');
$module = Parser::parseSource('import { x } from "./x.js"; export default x;', 'module');
```

`$sourceType` väljer grammatikens mål, namngivet efter samma alternativ i parsers för JS:

| Värde | Mål |
|---|---|
| `script` | klassiskt Script. `import`/`export` på toppnivå är syntaxfel, `await` är en identifierare |
| `module` | ES-modul. Implicit strikt läge; `import`/`export` och `await` på toppnivå kan parsas |

Alla andra värden kastar `\InvalidArgumentException`.

För mer detaljerad kontroll (förinställning av strikt läge för en direct-eval-kontext, läsning av `//# sourceURL`-pragmat) konstruerar du parsern direkt: `new Parser($source)` plus `setModuleMode()`, `setStrictMode()` och `parse()`.

## Noder

Varje AST-klass utökar `Phasis\Ast\Node` och finns under `Phasis\Ast\{Declaration, Expression, Pattern, Statement}`. Noderna är vanliga skrivskyddade värdeobjekt:

- `$node->type()` returnerar nodens typsträng, som är klassens basnamn (`'BinaryExpression'`, `'ArrowFunction'`, ...).
- `$node->location` är en `Phasis\Lexer\SourceLocation` med `line` (1-baserad), `column` (0-baserad) och `offset` (byteförskjutning). Endast startpositioner lagras; noder har ingen slutposition.
- Alla andra offentliga fält är nodens barn och attribut (`$binary->left`, `$binary->operator`, `$binary->right`).

De flesta typnamn motsvarar [ESTree](https://github.com/estree/estree). Avvikelserna:

| Typ i Phasis | ESTree-typ |
|---|---|
| `ArrowFunction` | `ArrowFunctionExpression` |
| `TaggedTemplate` | `TaggedTemplateExpression` |
| `ClassMethod` | `MethodDefinition` |
| `ClassProperty` | `PropertyDefinition` |
| `AssignmentProperty` | `Property` (inuti `ObjectPattern`) |
| `ExportDeclaration` | `ExportNamedDeclaration` / `ExportDefaultDeclaration` / `ExportAllDeclaration` |
| `ImportSpecifier` | `ImportSpecifier` / `ImportDefaultSpecifier` / `ImportNamespaceSpecifier` |

Några få former skiljer sig också: klasskroppar är en vanlig elementarray på klassnoden (utan omslaget `ClassBody`), import-/exportnamn, satsnamn och namn på `FunctionExpression` lagras som strängar i stället för nästlade noder av typen `Identifier`, och `super` parsas som en `Identifier` med namnet `super` (det finns ingen nodklass för `Super`). `Phasis\Ast\EstreeSerializer` omformar allt detta till ESTree-formatet.

## Syntaxfel

Ogiltig indata kastar `Phasis\Exceptions\SyntaxError` (vanligen dess underklass `Phasis\Parser\ParseError`). Undantagsmeddelandet avslutas med positionen, och den strukturerade platsen finns på undantaget:

```php
use Phasis\Exceptions\SyntaxError;
use Phasis\Parser\Parser;

try {
    Parser::parseSource("const a = 1;\nconst b = ;");
} catch (SyntaxError $e) {
    echo $e->getMessage();          // Unexpected token (got ; ";") at line 2, column 10
    echo $e->location->line;        // 2
    echo $e->location->column;      // 10
    echo $e->location->offset;      // 23
}
```

## Traverserare

`Phasis\Ast\Walker` traverserar ett träd djupet först med callbacks för enter/leave, i stil med estraverse:

```php
public static function walk(Node $node, callable $enter, ?callable $leave = null): void
```

Båda callbacks tar emot `(Node $node, ?Node $parent)`. Om `$enter` returnerar `Walker::SKIP` hoppas nodens barn över; nodens egen `$leave` körs ändå.

```php
use Phasis\Ast\Expression\Identifier;
use Phasis\Ast\Node;
use Phasis\Ast\Walker;

$names = [];
Walker::walk($program, function (Node $node) use (&$names) {
    if ($node instanceof Identifier) {
        $names[] = $node->name;
    }
    if ($node instanceof \Phasis\Ast\Expression\ArrowFunction) {
        return Walker::SKIP;
    }
});
```

Traverseringen är skrivskyddad. Noderna är skrivskyddade värdeobjekt, så det går inte att ersätta eller mutera dem.

## Serialiserare

`Phasis\Ast\Serializer` konverterar den typade AST:n till arrayer eller JSON med typnamn och fältlayout enligt Phasis, och tar bort cachefält som är interna för parsern:

```php
public static function toArray(Node $node): array
public static function toJson(Node $node, bool $pretty = false): string
```

Det här är formatet som `bin/phasis --ast` skriver ut.

## EstreeSerializer

`Phasis\Ast\EstreeSerializer` konverterar i stället den typade AST:n till ESTree-formade arrayer: typnamn enligt ESTree (utifrån avvikelsetabellen ovan), ESTree-fältnamn och ordning, genererade noder av typen `ClassBody` / specifier / source-`Literal` samt en `start`-byteförskjutning på varje nod som parsats från källan. Det finns inga `end`-förskjutningar eftersom noder bara lagrar startpositioner, och strängnoder av typen `Literal` innehåller ingen text i `raw`.

```php
public static function toArray(Node $node): array
public static function toJson(Node $node, bool $pretty = false): string
public static function summarize(Node $node): string
```

`summarize()` genererar en deterministisk sammanfattning med en rad per nod (typ plus attributen `name=` / `value=` / `op=` / `kind=`, två blanksteg per indenteringsnivå). Formatet är byteidentiskt med AST-sammanfattningen som acorn-fixturen i `tests/Popular/acorn` genererar, så samma oracle testar både parsersökvägen JS och denna export av typen PHP:

```php
use Phasis\Ast\EstreeSerializer;
use Phasis\Parser\Parser;

echo EstreeSerializer::summarize(Parser::parseSource('let x = a + 1;'));
// Program
//   VariableDeclaration kind=let
//     VariableDeclarator
//       Identifier name=x
//       BinaryExpression op=+
//         Identifier name=a
//         Literal value=1
```

## CLI

`bin/phasis --ast script.js` parsar en fil (Script-mål) och skriver ut `Serializer` JSON-dumpen med två blankstegs indrag. Se [CLI](https://phasis.inline0.dev/sv/docs/cli) för en fullständig referens till flaggorna.
