mirror of https://github.com/Wilfred/difftastic/
Use tree-sitter-php from crates.io
parent
f9d663ea9f
commit
eb0b47d403
@ -1 +0,0 @@
|
|||||||
../tree-sitter-php/queries/highlights.scm
|
|
||||||
@ -1 +0,0 @@
|
|||||||
tree-sitter-php/src
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
/src/** linguist-vendored
|
|
||||||
/examples/* linguist-vendored
|
|
||||||
/corpus/* linguist-vendored
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
Checklist:
|
|
||||||
- [ ] All tests pass in CI
|
|
||||||
- [ ] There are sufficient tests for the new fix/feature
|
|
||||||
- [ ] Grammar rules have not been renamed unless absolutely necessary (x rules renamed)
|
|
||||||
- [ ] The conflicts section hasn't grown too much (x new conflicts)
|
|
||||||
- [ ] The parser size hasn't grown too much (master: STATE_COUNT, PR: STATE_COUNT) (check the value of STATE_COUNT in src/parser.c)
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
name: Build/test
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- "**"
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- "master"
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: true
|
|
||||||
matrix:
|
|
||||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
- run: npm install
|
|
||||||
- run: npm test
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
package-lock.json
|
|
||||||
node_modules
|
|
||||||
build
|
|
||||||
*.log
|
|
||||||
.DS_Store
|
|
||||||
examples
|
|
||||||
|
|
||||||
*.a
|
|
||||||
*.dylib
|
|
||||||
*.so
|
|
||||||
*.o
|
|
||||||
bindings/c/*.h
|
|
||||||
bindings/c/tree-sitter-*.pc
|
|
||||||
.build/
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
test
|
|
||||||
build
|
|
||||||
script
|
|
||||||
examples
|
|
||||||
target
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "aho-corasick"
|
|
||||||
version = "0.7.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cc"
|
|
||||||
version = "1.0.73"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex"
|
|
||||||
version = "1.5.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-syntax",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-syntax"
|
|
||||||
version = "0.6.25"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tree-sitter"
|
|
||||||
version = "0.20.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "09b3b781640108d29892e8b9684642d2cda5ea05951fd58f0fea1db9edeb9b71"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"regex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tree-sitter-php"
|
|
||||||
version = "0.19.1"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"tree-sitter",
|
|
||||||
]
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "tree-sitter-php"
|
|
||||||
description = "php grammar for the tree-sitter parsing library"
|
|
||||||
version = "0.19.1"
|
|
||||||
keywords = ["incremental", "parsing", "php"]
|
|
||||||
categories = ["parsing", "text-editors"]
|
|
||||||
repository = "https://github.com/tree-sitter/tree-sitter-php"
|
|
||||||
edition = "2018"
|
|
||||||
|
|
||||||
build = "bindings/rust/build.rs"
|
|
||||||
include = [
|
|
||||||
"bindings/rust/*",
|
|
||||||
"grammar.js",
|
|
||||||
"queries/*",
|
|
||||||
"src/*",
|
|
||||||
]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
path = "bindings/rust/lib.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tree-sitter = ">= 0.19, < 0.21"
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
cc = "1.0"
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2017 Josh Vera, GitHub
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@ -1,114 +0,0 @@
|
|||||||
VERSION := 0.19.0
|
|
||||||
|
|
||||||
# Repository
|
|
||||||
SRC_DIR := src
|
|
||||||
|
|
||||||
PARSER_REPO_URL := $(shell git -C $(SRC_DIR) remote get-url origin )
|
|
||||||
|
|
||||||
ifeq (, $(PARSER_NAME))
|
|
||||||
PARSER_NAME := $(shell basename $(PARSER_REPO_URL))
|
|
||||||
PARSER_NAME := $(subst tree-sitter-,,$(PARSER_NAME))
|
|
||||||
PARSER_NAME := $(subst .git,,$(PARSER_NAME))
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq (, $(PARSER_URL))
|
|
||||||
PARSER_URL := $(subst :,/,$(PARSER_REPO_URL))
|
|
||||||
PARSER_URL := $(subst git@,https://,$(PARSER_URL))
|
|
||||||
PARSER_URL := $(subst .git,,$(PARSER_URL))
|
|
||||||
endif
|
|
||||||
|
|
||||||
UPPER_PARSER_NAME := $(shell echo $(PARSER_NAME) | tr a-z A-Z )
|
|
||||||
|
|
||||||
# install directory layout
|
|
||||||
PREFIX ?= /usr/local
|
|
||||||
INCLUDEDIR ?= $(PREFIX)/include
|
|
||||||
LIBDIR ?= $(PREFIX)/lib
|
|
||||||
PCLIBDIR ?= $(LIBDIR)/pkgconfig
|
|
||||||
|
|
||||||
# collect C++ sources, and link if necessary
|
|
||||||
CPPSRC := $(wildcard $(SRC_DIR)/*.cc)
|
|
||||||
|
|
||||||
ifeq (, $(CPPSRC))
|
|
||||||
ADDITIONALLIBS :=
|
|
||||||
else
|
|
||||||
ADDITIONALLIBS := -lc++
|
|
||||||
endif
|
|
||||||
|
|
||||||
# collect sources
|
|
||||||
SRC := $(wildcard $(SRC_DIR)/*.c)
|
|
||||||
SRC += $(CPPSRC)
|
|
||||||
OBJ := $(addsuffix .o,$(basename $(SRC)))
|
|
||||||
|
|
||||||
# ABI versioning
|
|
||||||
SONAME_MAJOR := 0
|
|
||||||
SONAME_MINOR := 0
|
|
||||||
|
|
||||||
CFLAGS ?= -O3 -Wall -Wextra -I$(SRC_DIR)
|
|
||||||
CXXFLAGS ?= -O3 -Wall -Wextra -I$(SRC_DIR)
|
|
||||||
override CFLAGS += -std=gnu99 -fPIC
|
|
||||||
override CXXFLAGS += -fPIC
|
|
||||||
|
|
||||||
# OS-specific bits
|
|
||||||
ifeq ($(shell uname),Darwin)
|
|
||||||
SOEXT = dylib
|
|
||||||
SOEXTVER_MAJOR = $(SONAME_MAJOR).dylib
|
|
||||||
SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).dylib
|
|
||||||
LINKSHARED := $(LINKSHARED)-dynamiclib -Wl,
|
|
||||||
ifneq ($(ADDITIONALLIBS),)
|
|
||||||
LINKSHARED := $(LINKSHARED)$(ADDITIONALLIBS),
|
|
||||||
endif
|
|
||||||
LINKSHARED := $(LINKSHARED)-install_name,$(LIBDIR)/libtree-sitter-$(PARSER_NAME).$(SONAME_MAJOR).dylib,-rpath,@executable_path/../Frameworks
|
|
||||||
else
|
|
||||||
SOEXT = so
|
|
||||||
SOEXTVER_MAJOR = so.$(SONAME_MAJOR)
|
|
||||||
SOEXTVER = so.$(SONAME_MAJOR).$(SONAME_MINOR)
|
|
||||||
LINKSHARED := $(LINKSHARED)-shared -Wl,
|
|
||||||
ifneq ($(ADDITIONALLIBS),)
|
|
||||||
LINKSHARED := $(LINKSHARED)$(ADDITIONALLIBS)
|
|
||||||
endif
|
|
||||||
LINKSHARED := $(LINKSHARED)-soname,libtree-sitter-$(PARSER_NAME).so.$(SONAME_MAJOR)
|
|
||||||
endif
|
|
||||||
ifneq (,$(filter $(shell uname),FreeBSD NetBSD DragonFly))
|
|
||||||
PCLIBDIR := $(PREFIX)/libdata/pkgconfig
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: libtree-sitter-$(PARSER_NAME).a libtree-sitter-$(PARSER_NAME).$(SOEXTVER) bindings/c/$(PARSER_NAME).h bindings/c/tree-sitter-$(PARSER_NAME).pc
|
|
||||||
|
|
||||||
libtree-sitter-$(PARSER_NAME).a: $(OBJ)
|
|
||||||
$(AR) rcs $@ $^
|
|
||||||
|
|
||||||
libtree-sitter-$(PARSER_NAME).$(SOEXTVER): $(OBJ)
|
|
||||||
$(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@
|
|
||||||
ln -sf $@ libtree-sitter-$(PARSER_NAME).$(SOEXT)
|
|
||||||
ln -sf $@ libtree-sitter-$(PARSER_NAME).$(SOEXTVER_MAJOR)
|
|
||||||
|
|
||||||
bindings/c/$(PARSER_NAME).h:
|
|
||||||
sed -e 's|@UPPER_PARSERNAME@|$(UPPER_PARSER_NAME)|' \
|
|
||||||
-e 's|@PARSERNAME@|$(PARSER_NAME)|' \
|
|
||||||
bindings/c/tree-sitter.h.in > $@
|
|
||||||
|
|
||||||
bindings/c/tree-sitter-$(PARSER_NAME).pc:
|
|
||||||
sed -e 's|@LIBDIR@|$(LIBDIR)|;s|@INCLUDEDIR@|$(INCLUDEDIR)|;s|@VERSION@|$(VERSION)|' \
|
|
||||||
-e 's|=$(PREFIX)|=$${prefix}|' \
|
|
||||||
-e 's|@PREFIX@|$(PREFIX)|' \
|
|
||||||
-e 's|@ADDITIONALLIBS@|$(ADDITIONALLIBS)|' \
|
|
||||||
-e 's|@PARSERNAME@|$(PARSER_NAME)|' \
|
|
||||||
-e 's|@PARSERURL@|$(PARSER_URL)|' \
|
|
||||||
bindings/c/tree-sitter.pc.in > $@
|
|
||||||
|
|
||||||
install: all
|
|
||||||
install -d '$(DESTDIR)$(LIBDIR)'
|
|
||||||
install -m755 libtree-sitter-$(PARSER_NAME).a '$(DESTDIR)$(LIBDIR)'/libtree-sitter-$(PARSER_NAME).a
|
|
||||||
install -m755 libtree-sitter-$(PARSER_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/libtree-sitter-$(PARSER_NAME).$(SOEXTVER)
|
|
||||||
ln -sf libtree-sitter-$(PARSER_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/libtree-sitter-$(PARSER_NAME).$(SOEXTVER_MAJOR)
|
|
||||||
ln -sf libtree-sitter-$(PARSER_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/libtree-sitter-$(PARSER_NAME).$(SOEXT)
|
|
||||||
install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter
|
|
||||||
install -m644 bindings/c/$(PARSER_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/
|
|
||||||
install -d '$(DESTDIR)$(PCLIBDIR)'
|
|
||||||
install -m644 bindings/c/tree-sitter-$(PARSER_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJ) libtree-sitter-$(PARSER_NAME).a libtree-sitter-$(PARSER_NAME).$(SOEXT) libtree-sitter-$(PARSER_NAME).$(SOEXTVER_MAJOR) libtree-sitter-$(PARSER_NAME).$(SOEXTVER)
|
|
||||||
rm -f bindings/c/$(PARSER_NAME).h bindings/c/tree-sitter-$(PARSER_NAME).pc
|
|
||||||
|
|
||||||
.PHONY: all install clean
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
// swift-tools-version:5.3
|
|
||||||
import PackageDescription
|
|
||||||
|
|
||||||
let package = Package(
|
|
||||||
name: "TreeSitterPHP",
|
|
||||||
products: [
|
|
||||||
.library(name: "TreeSitterPHP", targets: ["TreeSitterPHP"]),
|
|
||||||
],
|
|
||||||
dependencies: [],
|
|
||||||
targets: [
|
|
||||||
.target(name: "TreeSitterPHP",
|
|
||||||
path: ".",
|
|
||||||
exclude: [
|
|
||||||
"binding.gyp",
|
|
||||||
"bindings",
|
|
||||||
"Cargo.toml",
|
|
||||||
"corpus",
|
|
||||||
"grammar.js",
|
|
||||||
"LICENSE",
|
|
||||||
"Makefile",
|
|
||||||
"package.json",
|
|
||||||
"README.md",
|
|
||||||
"script",
|
|
||||||
"src/grammar.json",
|
|
||||||
"src/node-types.json",
|
|
||||||
],
|
|
||||||
sources: [
|
|
||||||
"src/parser.c",
|
|
||||||
"src/scanner.cc",
|
|
||||||
],
|
|
||||||
resources: [
|
|
||||||
.copy("queries")
|
|
||||||
],
|
|
||||||
publicHeadersPath: "bindings/swift",
|
|
||||||
cSettings: [.headerSearchPath("src")])
|
|
||||||
]
|
|
||||||
)
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
tree-sitter-php
|
|
||||||
==================
|
|
||||||
|
|
||||||
[](https://github.com/tree-sitter/tree-sitter-php/actions/workflows/ci.yml)
|
|
||||||
|
|
||||||
PHP grammar for [tree-sitter][].
|
|
||||||
|
|
||||||
[tree-sitter]: https://github.com/tree-sitter/tree-sitter
|
|
||||||
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"target_name": "tree_sitter_php_binding",
|
|
||||||
"include_dirs": [
|
|
||||||
"<!(node -e \"require('nan')\")",
|
|
||||||
"src"
|
|
||||||
],
|
|
||||||
"sources": [
|
|
||||||
"src/parser.c",
|
|
||||||
"src/scanner.cc",
|
|
||||||
"bindings/node/binding.cc"
|
|
||||||
],
|
|
||||||
"cflags_c": [
|
|
||||||
"-std=c99"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
#ifndef TREE_SITTER_@UPPER_PARSERNAME@_H_
|
|
||||||
#define TREE_SITTER_@UPPER_PARSERNAME@_H_
|
|
||||||
|
|
||||||
#include <tree_sitter/parser.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern TSLanguage *tree_sitter_@PARSERNAME@();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // TREE_SITTER_@UPPER_PARSERNAME@_H_
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
prefix=@PREFIX@
|
|
||||||
libdir=@LIBDIR@
|
|
||||||
includedir=@INCLUDEDIR@
|
|
||||||
additionallibs=@ADDITIONALLIBS@
|
|
||||||
|
|
||||||
Name: tree-sitter-@PARSERNAME@
|
|
||||||
Description: A tree-sitter grammar for the @PARSERNAME@ programming language.
|
|
||||||
URL: @PARSERURL@
|
|
||||||
Version: @VERSION@
|
|
||||||
Libs: -L${libdir} ${additionallibs} -ltree-sitter-@PARSERNAME@
|
|
||||||
Cflags: -I${includedir}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
#include "tree_sitter/parser.h"
|
|
||||||
#include <node.h>
|
|
||||||
#include "nan.h"
|
|
||||||
|
|
||||||
using namespace v8;
|
|
||||||
|
|
||||||
extern "C" TSLanguage * tree_sitter_php();
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
NAN_METHOD(New) {}
|
|
||||||
|
|
||||||
void Init(Local<Object> exports, Local<Object> module) {
|
|
||||||
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
|
|
||||||
tpl->SetClassName(Nan::New("Language").ToLocalChecked());
|
|
||||||
tpl->InstanceTemplate()->SetInternalFieldCount(1);
|
|
||||||
|
|
||||||
Local<Function> constructor = Nan::GetFunction(tpl).ToLocalChecked();
|
|
||||||
Local<Object> instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
|
|
||||||
Nan::SetInternalFieldPointer(instance, 0, tree_sitter_php());
|
|
||||||
|
|
||||||
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("php").ToLocalChecked());
|
|
||||||
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
NODE_MODULE(tree_sitter_php_binding, Init)
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
try {
|
|
||||||
module.exports = require("../../build/Release/tree_sitter_php_binding");
|
|
||||||
} catch (error1) {
|
|
||||||
if (error1.code !== 'MODULE_NOT_FOUND') {
|
|
||||||
throw error1;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
module.exports = require("../../build/Debug/tree_sitter_php_binding");
|
|
||||||
} catch (error2) {
|
|
||||||
if (error2.code !== 'MODULE_NOT_FOUND') {
|
|
||||||
throw error2;
|
|
||||||
}
|
|
||||||
throw error1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
module.exports.nodeTypeInfo = require("../../src/node-types.json");
|
|
||||||
} catch (_) {}
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
# tree-sitter-php
|
|
||||||
|
|
||||||
This crate provides support of the PHP language for the [tree-sitter][] parsing library. To use this crate, add it to
|
|
||||||
the `[dependencies]` section of your
|
|
||||||
`Cargo.toml` file. As this crate is not (yet) published to the central registry, you will have to specify it as a git
|
|
||||||
dependency, currently we suggest using the `master` branch.
|
|
||||||
|
|
||||||
You will also need the [tree-sitter crate][] to do the actual parsing here.
|
|
||||||
|
|
||||||
``` toml
|
|
||||||
[dependencies]
|
|
||||||
tree-sitter = "0.19"
|
|
||||||
tree-sitter-php = { git = "https://github.com/tree-sitter/tree-sitter-php.git", branch = "master" }
|
|
||||||
```
|
|
||||||
|
|
||||||
To you the parser, you need to obtain an instance of a [`tree_sitter::Language`][Language] struct for php.
|
|
||||||
The `language()` function provides this.
|
|
||||||
Passing this struct to a [`tree_sitter::Parser`][Parser] will enable it to parse PHP.
|
|
||||||
|
|
||||||
``` rust
|
|
||||||
use tree_sitter::Parser;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let code = r#"
|
|
||||||
function double(int $x) {
|
|
||||||
return $x * 2;
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
let mut parser = Parser::new();
|
|
||||||
parser
|
|
||||||
.set_language(tree_sitter_php::language())
|
|
||||||
.expect("Error loading PHP parsing support");
|
|
||||||
let parsed = parser.parse(code, None);
|
|
||||||
println!("{:#?}", parsed);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If you have any questions, please reach out to us in the [tree-sitter discussions] page.
|
|
||||||
|
|
||||||
[Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
|
|
||||||
|
|
||||||
[Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
|
|
||||||
|
|
||||||
[tree-sitter]: https://tree-sitter.github.io/
|
|
||||||
|
|
||||||
[tree-sitter crate]: https://crates.io/crates/tree-sitter
|
|
||||||
|
|
||||||
[tree-sitter discussions]: https://github.com/tree-sitter/tree-sitter/discussions
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
let src_dir = std::path::Path::new("src");
|
|
||||||
|
|
||||||
let mut c_config = cc::Build::new();
|
|
||||||
c_config.include(&src_dir);
|
|
||||||
c_config
|
|
||||||
.flag_if_supported("-Wno-unused-parameter")
|
|
||||||
.flag_if_supported("-Wno-unused-but-set-variable")
|
|
||||||
.flag_if_supported("-Wno-trigraphs");
|
|
||||||
let parser_path = src_dir.join("parser.c");
|
|
||||||
c_config.file(&parser_path);
|
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
|
|
||||||
c_config.compile("parser");
|
|
||||||
|
|
||||||
// If your language uses an external scanner written in C++,
|
|
||||||
// then include this block of code:
|
|
||||||
|
|
||||||
let mut cpp_config = cc::Build::new();
|
|
||||||
cpp_config.cpp(true);
|
|
||||||
cpp_config.include(&src_dir);
|
|
||||||
cpp_config
|
|
||||||
.flag_if_supported("-Wno-unused-parameter")
|
|
||||||
.flag_if_supported("-Wno-unused-but-set-variable");
|
|
||||||
let scanner_path = src_dir.join("scanner.cc");
|
|
||||||
cpp_config.file(&scanner_path);
|
|
||||||
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
|
|
||||||
cpp_config.compile("scanner");
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
//! This crate provides php language support for the [tree-sitter][] parsing library.
|
|
||||||
//!
|
|
||||||
//! Typically, you will use the [language][language func] function to add this language to a
|
|
||||||
//! tree-sitter [Parser][], and then use the parser to parse some code:
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! let code = "";
|
|
||||||
//! let mut parser = tree_sitter::Parser::new();
|
|
||||||
//! parser.set_language(tree_sitter_php::language()).expect("Error loading php grammar");
|
|
||||||
//! let tree = parser.parse(code, None).unwrap();
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
|
|
||||||
//! [language func]: fn.language.html
|
|
||||||
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
|
|
||||||
//! [tree-sitter]: https://tree-sitter.github.io/
|
|
||||||
|
|
||||||
use tree_sitter::Language;
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
fn tree_sitter_php() -> Language;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the tree-sitter [Language][] for this grammar.
|
|
||||||
///
|
|
||||||
/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
|
|
||||||
pub fn language() -> Language {
|
|
||||||
unsafe { tree_sitter_php() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The content of the [`node-types.json`][] file for this grammar.
|
|
||||||
///
|
|
||||||
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
|
|
||||||
pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json");
|
|
||||||
|
|
||||||
// Uncomment these to include any queries that this grammar contains
|
|
||||||
|
|
||||||
pub const HIGHLIGHT_QUERY: &'static str = include_str!("../../queries/highlights.scm");
|
|
||||||
pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm");
|
|
||||||
// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm");
|
|
||||||
pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm");
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
#[test]
|
|
||||||
fn test_can_load_grammar() {
|
|
||||||
let mut parser = tree_sitter::Parser::new();
|
|
||||||
parser
|
|
||||||
.set_language(super::language())
|
|
||||||
.expect("Error loading php language");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
#ifndef TREE_SITTER_PHP_H_
|
|
||||||
#define TREE_SITTER_PHP_H_
|
|
||||||
|
|
||||||
typedef struct TSLanguage TSLanguage;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern TSLanguage *tree_sitter_php();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // TREE_SITTER_PHP_H_
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,40 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "tree-sitter-php",
|
|
||||||
"version": "0.19.0",
|
|
||||||
"description": "PHP grammar for tree-sitter",
|
|
||||||
"main": "bindings/node",
|
|
||||||
"keywords": [
|
|
||||||
"parser",
|
|
||||||
"php"
|
|
||||||
],
|
|
||||||
"author": "Josh Vera",
|
|
||||||
"license": "MIT",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/tree-sitter/tree-sitter-php/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/tree-sitter/tree-sitter-php#readme",
|
|
||||||
"dependencies": {
|
|
||||||
"nan": "^2.14.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"tree-sitter-cli": "^0.19.1",
|
|
||||||
"shelljs": "^0.8.4"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"build": "tree-sitter generate && node-gyp build",
|
|
||||||
"test": "tree-sitter test && node script/parse-examples.js"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/tree-sitter/tree-sitter-php.git"
|
|
||||||
},
|
|
||||||
"tree-sitter": [
|
|
||||||
{
|
|
||||||
"scope": "source.php",
|
|
||||||
"file-types": [
|
|
||||||
"php"
|
|
||||||
],
|
|
||||||
"highlights": "queries/highlights.scm"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,115 +0,0 @@
|
|||||||
(php_tag) @tag
|
|
||||||
"?>" @tag
|
|
||||||
|
|
||||||
; Types
|
|
||||||
|
|
||||||
(primitive_type) @type.builtin
|
|
||||||
(cast_type) @type.builtin
|
|
||||||
(named_type (name) @type) @type
|
|
||||||
(named_type (qualified_name) @type) @type
|
|
||||||
|
|
||||||
; Functions
|
|
||||||
|
|
||||||
(array_creation_expression "array" @function.builtin)
|
|
||||||
(list_literal "list" @function.builtin)
|
|
||||||
|
|
||||||
(method_declaration
|
|
||||||
name: (name) @function.method)
|
|
||||||
|
|
||||||
(function_call_expression
|
|
||||||
function: (qualified_name (name)) @function)
|
|
||||||
|
|
||||||
(scoped_call_expression
|
|
||||||
name: (name) @function)
|
|
||||||
|
|
||||||
(member_call_expression
|
|
||||||
name: (name) @function.method)
|
|
||||||
|
|
||||||
(function_definition
|
|
||||||
name: (name) @function)
|
|
||||||
|
|
||||||
; Member
|
|
||||||
|
|
||||||
(property_element
|
|
||||||
(variable_name) @property)
|
|
||||||
|
|
||||||
(member_access_expression
|
|
||||||
name: (variable_name (name)) @property)
|
|
||||||
(member_access_expression
|
|
||||||
name: (name) @property)
|
|
||||||
|
|
||||||
; Variables
|
|
||||||
|
|
||||||
(relative_scope) @variable.builtin
|
|
||||||
|
|
||||||
((name) @constant
|
|
||||||
(#match? @constant "^_?[A-Z][A-Z\\d_]+$"))
|
|
||||||
|
|
||||||
((name) @constructor
|
|
||||||
(#match? @constructor "^[A-Z]"))
|
|
||||||
|
|
||||||
((name) @variable.builtin
|
|
||||||
(#eq? @variable.builtin "this"))
|
|
||||||
|
|
||||||
(variable_name) @variable
|
|
||||||
|
|
||||||
; Basic tokens
|
|
||||||
|
|
||||||
(string) @string
|
|
||||||
(heredoc) @string
|
|
||||||
(boolean) @constant.builtin
|
|
||||||
(null) @constant.builtin
|
|
||||||
(integer) @number
|
|
||||||
(float) @number
|
|
||||||
(comment) @comment
|
|
||||||
|
|
||||||
"$" @operator
|
|
||||||
|
|
||||||
; Keywords
|
|
||||||
|
|
||||||
"abstract" @keyword
|
|
||||||
"as" @keyword
|
|
||||||
"break" @keyword
|
|
||||||
"case" @keyword
|
|
||||||
"catch" @keyword
|
|
||||||
"class" @keyword
|
|
||||||
"const" @keyword
|
|
||||||
"continue" @keyword
|
|
||||||
"declare" @keyword
|
|
||||||
"default" @keyword
|
|
||||||
"do" @keyword
|
|
||||||
"echo" @keyword
|
|
||||||
"else" @keyword
|
|
||||||
"elseif" @keyword
|
|
||||||
"enddeclare" @keyword
|
|
||||||
"endforeach" @keyword
|
|
||||||
"endif" @keyword
|
|
||||||
"endswitch" @keyword
|
|
||||||
"endwhile" @keyword
|
|
||||||
"extends" @keyword
|
|
||||||
"final" @keyword
|
|
||||||
"finally" @keyword
|
|
||||||
"foreach" @keyword
|
|
||||||
"function" @keyword
|
|
||||||
"global" @keyword
|
|
||||||
"if" @keyword
|
|
||||||
"implements" @keyword
|
|
||||||
"include_once" @keyword
|
|
||||||
"include" @keyword
|
|
||||||
"insteadof" @keyword
|
|
||||||
"interface" @keyword
|
|
||||||
"namespace" @keyword
|
|
||||||
"new" @keyword
|
|
||||||
"private" @keyword
|
|
||||||
"protected" @keyword
|
|
||||||
"public" @keyword
|
|
||||||
"require_once" @keyword
|
|
||||||
"require" @keyword
|
|
||||||
"return" @keyword
|
|
||||||
"static" @keyword
|
|
||||||
"switch" @keyword
|
|
||||||
"throw" @keyword
|
|
||||||
"trait" @keyword
|
|
||||||
"try" @keyword
|
|
||||||
"use" @keyword
|
|
||||||
"while" @keyword
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
((text) @injection.content
|
|
||||||
(#set! injection.language "html")
|
|
||||||
(#set! injection.combined))
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
(class_declaration
|
|
||||||
name: (name) @name) @definition.class
|
|
||||||
|
|
||||||
(function_definition
|
|
||||||
name: (name) @name) @definition.function
|
|
||||||
|
|
||||||
(method_declaration
|
|
||||||
name: (name) @name) @definition.function
|
|
||||||
|
|
||||||
(object_creation_expression
|
|
||||||
[
|
|
||||||
(qualified_name (name) @name)
|
|
||||||
(variable_name (name) @name)
|
|
||||||
]) @reference.class
|
|
||||||
|
|
||||||
(function_call_expression
|
|
||||||
function: [
|
|
||||||
(qualified_name (name) @name)
|
|
||||||
(variable_name (name)) @name
|
|
||||||
]) @reference.call
|
|
||||||
|
|
||||||
(scoped_call_expression
|
|
||||||
name: (name) @name) @reference.call
|
|
||||||
|
|
||||||
(member_call_expression
|
|
||||||
name: (name) @name) @reference.call
|
|
||||||
@ -1 +0,0 @@
|
|||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
cd "$(dirname "$0")/.."
|
|
||||||
|
|
||||||
function checkout_at() {
|
|
||||||
path="examples/$1"
|
|
||||||
url=$2
|
|
||||||
sha=$3
|
|
||||||
|
|
||||||
if [ ! -d "$path" ]; then
|
|
||||||
git clone "https://github.com/$url" "$path"
|
|
||||||
fi
|
|
||||||
|
|
||||||
pushd "$path"
|
|
||||||
git fetch && git reset --hard "$sha"
|
|
||||||
popd
|
|
||||||
}
|
|
||||||
|
|
||||||
checkout_at "laravel" "laravel/laravel" "9d0862b3340c8243ee072afc181e315ffa35e110"
|
|
||||||
checkout_at "phabricator" "phacility/phabricator" "d0b01a41f2498fb2a6487c2d6704dc7acfd4675f"
|
|
||||||
checkout_at "phpunit" "sebastianbergmann/phpunit" "5e523bdc7dd4d90fed9fb29d1df05347b3e7eaba"
|
|
||||||
checkout_at "WordPress" "WordPress/WordPress" "45286c5bb3f6fe5005567903ec858d87077eae2c"
|
|
||||||
|
|
||||||
known_failures="$(cat script/known-failures.txt)"
|
|
||||||
|
|
||||||
tree-sitter parse -q \
|
|
||||||
'examples/**/*.php' \
|
|
||||||
$(for file in $known_failures; do echo "!${file}"; done)
|
|
||||||
|
|
||||||
example_count=$(find examples -name '*.php' | wc -l)
|
|
||||||
failure_count=$(wc -w <<< "$known_failures")
|
|
||||||
success_count=$(( $example_count - $failure_count ))
|
|
||||||
success_percent=$(bc -l <<< "100*${success_count}/${example_count}")
|
|
||||||
|
|
||||||
printf \
|
|
||||||
"Successfully parsed %d of %d example files (%.1f%%)\n" \
|
|
||||||
$success_count $example_count $success_percent
|
|
||||||
@ -1,102 +0,0 @@
|
|||||||
const fs = require('fs')
|
|
||||||
const os = require('os')
|
|
||||||
const util = require('util');
|
|
||||||
const { exec, execSync } = require('child_process')
|
|
||||||
const shell = require('shelljs')
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
checkoutExampleProjects([
|
|
||||||
{ dir: 'laravel', repository: 'https://github.com/laravel/laravel', sha: '9d0862b3340c8243ee072afc181e315ffa35e110' },
|
|
||||||
{ dir: 'framework', repository: 'https://github.com/laravel/framework', sha: '45d439e98a6b14afde8911f7d22a265948adbf72' },
|
|
||||||
{ dir: 'phabricator', repository: 'https://github.com/phacility/phabricator', sha: 'd0b01a41f2498fb2a6487c2d6704dc7acfd4675f' },
|
|
||||||
{ dir: 'phpunit', repository: 'https://github.com/sebastianbergmann/phpunit', sha: '5e523bdc7dd4d90fed9fb29d1df05347b3e7eaba' },
|
|
||||||
{ dir: 'WordPress', repository: 'https://github.com/WordPress/WordPress', sha: '45286c5bb3f6fe5005567903ec858d87077eae2c' },
|
|
||||||
{ dir: 'mediawiki', repository: 'https://github.com/wikimedia/mediawiki', sha: 'b6b88cbf98fb0c7891324709a85eabc290ed28b4' },
|
|
||||||
])
|
|
||||||
|
|
||||||
parseExamples()
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseExamples() {
|
|
||||||
const knownFailures = loadKnownFailures().split(/\r\n|\n/).filter(line => line.length > 0)
|
|
||||||
|
|
||||||
let excludeString = knownFailures.join(" !")
|
|
||||||
if (knownFailures.length > 0) {
|
|
||||||
excludeString = "!" + excludeString
|
|
||||||
}
|
|
||||||
|
|
||||||
if (os.platform == 'win32') {
|
|
||||||
excludeString = convertToWindowsPath(excludeString)
|
|
||||||
}
|
|
||||||
|
|
||||||
exec('"./node_modules/.bin/tree-sitter" parse -q examples/**/*.php ' + excludeString, (err, stdout) => {
|
|
||||||
const failures = extractFailureFilePaths(stdout)
|
|
||||||
failures.forEach(failure => {
|
|
||||||
if (!knownFailures.includes(failure)) {
|
|
||||||
console.error(`Unknown failure occurred: ${failure}`)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const failureCount = failures.length + knownFailures.length
|
|
||||||
const exampleCount = countExampleFiles()
|
|
||||||
const successCount = exampleCount - failureCount;
|
|
||||||
const successPercent = 100 * successCount / exampleCount
|
|
||||||
|
|
||||||
console.log(`Successfully parsed ${successCount} of ${exampleCount} example files (${successPercent.toFixed(2)}%)`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractFailureFilePaths(stdout) {
|
|
||||||
return stdout.split(/\r\n|\n/).filter(line => line.length > 0).map(line => convertToUnixPath(line.substring(0, line.indexOf(" "))))
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertToUnixPath(filePathString) {
|
|
||||||
return filePathString.split("\\").join("/")
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertToWindowsPath(filePathString) {
|
|
||||||
return filePathString.split("/").join("\\")
|
|
||||||
}
|
|
||||||
|
|
||||||
function countExampleFiles() {
|
|
||||||
return shell.find('./examples').filter((file) => { return file.match(/\.php$/) }).length
|
|
||||||
}
|
|
||||||
|
|
||||||
function createExamplesDirectoryIfNotExists() {
|
|
||||||
const dir = './examples'
|
|
||||||
|
|
||||||
if (!fs.existsSync(dir)) {
|
|
||||||
fs.mkdirSync(dir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkoutExampleProjects(projects) {
|
|
||||||
createExamplesDirectoryIfNotExists()
|
|
||||||
|
|
||||||
checkoutPromise = util.promisify(checkoutExampleProject)
|
|
||||||
|
|
||||||
Promise.all(projects.map((project) => checkoutPromise(project)))
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkoutExampleProject(project) {
|
|
||||||
const projectDir = './examples/' + project.dir
|
|
||||||
if (!fs.existsSync(projectDir)) {
|
|
||||||
cloneRepository(project)
|
|
||||||
}
|
|
||||||
|
|
||||||
checkoutCommit(project)
|
|
||||||
}
|
|
||||||
|
|
||||||
function cloneRepository(project) {
|
|
||||||
execSync('cd examples && git clone --quiet ' + project.repository + ' ' + project.dir + ' && cd ..')
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkoutCommit(project) {
|
|
||||||
execSync('cd examples/' + project.dir + ' && git fetch --quiet && git reset --quiet --hard "' + project.sha + '" && cd ../..')
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadKnownFailures() {
|
|
||||||
return fs.readFileSync('./script/known-failures.txt').toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,465 +0,0 @@
|
|||||||
#include <tree_sitter/parser.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <cwctype>
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
using std::vector;
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
enum TokenType {
|
|
||||||
AUTOMATIC_SEMICOLON,
|
|
||||||
ENCAPSED_STRING_CHARS,
|
|
||||||
ENCAPSED_STRING_CHARS_AFTER_VARIABLE,
|
|
||||||
ENCAPSED_STRING_CHARS_HEREDOC,
|
|
||||||
ENCAPSED_STRING_CHARS_AFTER_VARIABLE_HEREDOC,
|
|
||||||
EOF_TOKEN,
|
|
||||||
HEREDOC_START,
|
|
||||||
HEREDOC_END,
|
|
||||||
NOWDOC_STRING,
|
|
||||||
SENTINEL_ERROR, // Unused token used to indicate error recovery mode
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Heredoc {
|
|
||||||
Heredoc() : end_word_indentation_allowed(false) {}
|
|
||||||
|
|
||||||
string word;
|
|
||||||
bool end_word_indentation_allowed;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Scanner {
|
|
||||||
bool has_leading_whitespace;
|
|
||||||
vector<Heredoc> open_heredocs;
|
|
||||||
|
|
||||||
Scanner() : has_leading_whitespace(false) {}
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
open_heredocs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ScanContentResult {
|
|
||||||
Error,
|
|
||||||
End
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned serialize(char *buffer) {
|
|
||||||
unsigned i = 0;
|
|
||||||
|
|
||||||
buffer[i++] = open_heredocs.size();
|
|
||||||
for (
|
|
||||||
vector<Heredoc>::iterator iter = open_heredocs.begin(),
|
|
||||||
end = open_heredocs.end();
|
|
||||||
iter != end;
|
|
||||||
++iter
|
|
||||||
) {
|
|
||||||
if (i + 2 + iter->word.size() >= TREE_SITTER_SERIALIZATION_BUFFER_SIZE) return 0;
|
|
||||||
buffer[i++] = iter->end_word_indentation_allowed;
|
|
||||||
buffer[i++] = iter->word.size();
|
|
||||||
iter->word.copy(&buffer[i], iter->word.size());
|
|
||||||
i += iter->word.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void deserialize(const char *buffer, unsigned length) {
|
|
||||||
unsigned i = 0;
|
|
||||||
has_leading_whitespace = false;
|
|
||||||
open_heredocs.clear();
|
|
||||||
|
|
||||||
if (length == 0) return;
|
|
||||||
|
|
||||||
uint8_t open_heredoc_count = buffer[i++];
|
|
||||||
for (unsigned j = 0; j < open_heredoc_count; j++) {
|
|
||||||
Heredoc heredoc;
|
|
||||||
heredoc.end_word_indentation_allowed = buffer[i++];
|
|
||||||
uint8_t word_length = buffer[i++];
|
|
||||||
heredoc.word.assign(buffer + i, buffer + i + word_length);
|
|
||||||
i += word_length;
|
|
||||||
open_heredocs.push_back(heredoc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert(i == length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void skip(TSLexer *lexer) {
|
|
||||||
has_leading_whitespace = true;
|
|
||||||
lexer->advance(lexer, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void advance(TSLexer *lexer) {
|
|
||||||
lexer->advance(lexer, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool scan_whitespace(TSLexer *lexer) {
|
|
||||||
for (;;) {
|
|
||||||
while (iswspace(lexer->lookahead)) {
|
|
||||||
advance(lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lexer->lookahead == '/') {
|
|
||||||
advance(lexer);
|
|
||||||
|
|
||||||
if (lexer->lookahead == '/') {
|
|
||||||
advance(lexer);
|
|
||||||
while (lexer->lookahead != 0 && lexer->lookahead != '\n') {
|
|
||||||
advance(lexer);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_valid_name_char(TSLexer *lexer) {
|
|
||||||
return iswalpha(lexer->lookahead) || lexer->lookahead == '_';
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_escapable_sequence(TSLexer *lexer) {
|
|
||||||
// Note: remember to also update the escape_sequence rule in the
|
|
||||||
// main grammar whenever changing this method
|
|
||||||
int32_t letter = lexer->lookahead;
|
|
||||||
|
|
||||||
if (letter == 'n' ||
|
|
||||||
letter == 'r' ||
|
|
||||||
letter == 't' ||
|
|
||||||
letter == 'v' ||
|
|
||||||
letter == 'e' ||
|
|
||||||
letter == 'f' ||
|
|
||||||
letter == '\\' ||
|
|
||||||
letter == '$' ||
|
|
||||||
letter == '"') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hex
|
|
||||||
if (letter == 'x') {
|
|
||||||
advance(lexer);
|
|
||||||
return isxdigit(lexer->lookahead);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unicode
|
|
||||||
if (letter == 'u') {
|
|
||||||
return true; // We handle the case where this is not really an escape sequence in grammar.js - this is needed to support the edge case "\u{$a}" in which case "\u" is to be interprented as characters and {$a} as a variable
|
|
||||||
}
|
|
||||||
|
|
||||||
// Octal
|
|
||||||
return iswdigit(lexer->lookahead) && lexer->lookahead >= '0' && lexer->lookahead <= '7';
|
|
||||||
}
|
|
||||||
|
|
||||||
bool scan_nowdoc_string(TSLexer *lexer) {
|
|
||||||
bool has_consumed_content = false;
|
|
||||||
if (open_heredocs.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// While PHP requires the nowdoc end tag to be the very first on a new line, there may be an
|
|
||||||
// arbitrary amount of whitespace before the closing token
|
|
||||||
while (iswspace(lexer->lookahead)) {
|
|
||||||
advance(lexer);
|
|
||||||
has_consumed_content = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
string heredoc_tag = open_heredocs.back().word;
|
|
||||||
|
|
||||||
bool end_tag_matched = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < heredoc_tag.length(); i++) {
|
|
||||||
if (lexer->lookahead != heredoc_tag[i]) break;
|
|
||||||
advance(lexer);
|
|
||||||
has_consumed_content = true;
|
|
||||||
|
|
||||||
end_tag_matched = (i == heredoc_tag.length() - 1 && (iswspace(lexer->lookahead) || lexer->lookahead == ';' || lexer->lookahead == ',' || lexer->lookahead == ')'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_tag_matched) {
|
|
||||||
// There may be an arbitrary amount of white space after the end tag
|
|
||||||
while (iswspace(lexer->lookahead) && lexer->lookahead != '\r' && lexer->lookahead != '\n') {
|
|
||||||
advance(lexer);
|
|
||||||
has_consumed_content = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return to allow the end tag parsing if we've encountered an end tag at a valid position
|
|
||||||
if (lexer->lookahead == ';' || lexer->lookahead == ',' || lexer->lookahead == ')' || lexer->lookahead == '\n' || lexer->lookahead == '\r') {
|
|
||||||
// , and ) is needed to support heredoc in function arguments
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (bool has_content = has_consumed_content;; has_content = true) {
|
|
||||||
lexer->mark_end(lexer);
|
|
||||||
|
|
||||||
switch (lexer->lookahead) {
|
|
||||||
case '\n':
|
|
||||||
case '\r':
|
|
||||||
return has_content;
|
|
||||||
default:
|
|
||||||
if (lexer->eof(lexer)) return false;
|
|
||||||
advance(lexer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool scan_encapsed_part_string(TSLexer *lexer, bool is_after_variable, bool is_heredoc) {
|
|
||||||
bool has_consumed_content = false;
|
|
||||||
|
|
||||||
if (is_heredoc && !open_heredocs.empty()) {
|
|
||||||
// While PHP requires the heredoc end tag to be the very first on a new line, there may be an
|
|
||||||
// arbitrary amount of whitespace before the closing token
|
|
||||||
// However, we should not consume \r or \n
|
|
||||||
while (iswspace(lexer->lookahead) && lexer->lookahead != '\r' && lexer->lookahead != '\n') {
|
|
||||||
advance(lexer);
|
|
||||||
has_consumed_content = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
string heredoc_tag = open_heredocs.back().word;
|
|
||||||
|
|
||||||
bool end_tag_matched = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < heredoc_tag.length(); i++) {
|
|
||||||
if (lexer->lookahead != heredoc_tag[i]) break;
|
|
||||||
has_consumed_content = true;
|
|
||||||
advance(lexer);
|
|
||||||
|
|
||||||
end_tag_matched = (i == heredoc_tag.length() - 1 && (iswspace(lexer->lookahead) || lexer->lookahead == ';' || lexer->lookahead == ',' || lexer->lookahead == ')'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end_tag_matched) {
|
|
||||||
// There may be an arbitrary amount of white space after the end tag
|
|
||||||
// However, we should not consume \r or \n
|
|
||||||
while (iswspace(lexer->lookahead) && lexer->lookahead != '\r' && lexer->lookahead != '\n') {
|
|
||||||
advance(lexer);
|
|
||||||
has_consumed_content = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return to allow the end tag parsing if we've encountered an end tag at a valid position
|
|
||||||
if (lexer->lookahead == ';' || lexer->lookahead == ',' || lexer->lookahead == ')' || lexer->lookahead == '\n' || lexer->lookahead == '\r') {
|
|
||||||
// , and ) is needed to support heredoc in function arguments
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (bool has_content = has_consumed_content;; has_content = true) {
|
|
||||||
lexer->mark_end(lexer);
|
|
||||||
|
|
||||||
switch (lexer->lookahead) {
|
|
||||||
case '"':
|
|
||||||
if (!is_heredoc) {
|
|
||||||
return has_content;
|
|
||||||
}
|
|
||||||
advance(lexer);
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
case '\r':
|
|
||||||
if (is_heredoc) {
|
|
||||||
return has_content;
|
|
||||||
}
|
|
||||||
advance(lexer);
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
advance(lexer);
|
|
||||||
|
|
||||||
// \{ should not be interprented as an escape sequence, but both
|
|
||||||
// should be consumed as normal characters
|
|
||||||
if (lexer->lookahead == '{') {
|
|
||||||
advance(lexer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_heredoc && lexer->lookahead == '\\') {
|
|
||||||
advance(lexer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_escapable_sequence(lexer)) {
|
|
||||||
return has_content;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '$':
|
|
||||||
advance(lexer);
|
|
||||||
|
|
||||||
if (is_valid_name_char(lexer) || lexer->lookahead == '{') {
|
|
||||||
return has_content;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
if (is_after_variable) {
|
|
||||||
advance(lexer);
|
|
||||||
if (lexer->lookahead == '>') {
|
|
||||||
advance(lexer);
|
|
||||||
if (is_valid_name_char(lexer)) {
|
|
||||||
return has_content;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case '[':
|
|
||||||
if (is_after_variable) {
|
|
||||||
return has_content;
|
|
||||||
}
|
|
||||||
advance(lexer);
|
|
||||||
break;
|
|
||||||
case '{':
|
|
||||||
advance(lexer);
|
|
||||||
if (lexer->lookahead == '$') {
|
|
||||||
return has_content;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (lexer->eof(lexer)) return false;
|
|
||||||
advance(lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
is_after_variable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string scan_heredoc_word(TSLexer *lexer) {
|
|
||||||
string result;
|
|
||||||
|
|
||||||
while (is_valid_name_char(lexer)) {
|
|
||||||
result += lexer->lookahead;
|
|
||||||
advance(lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool scan(TSLexer *lexer, const bool *valid_symbols) {
|
|
||||||
const bool is_error_recovery = valid_symbols[SENTINEL_ERROR];
|
|
||||||
|
|
||||||
if (is_error_recovery) {
|
|
||||||
// Consider if we should clear the heredoc list on error
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
has_leading_whitespace = false;
|
|
||||||
|
|
||||||
lexer->mark_end(lexer);
|
|
||||||
|
|
||||||
if (valid_symbols[ENCAPSED_STRING_CHARS_AFTER_VARIABLE]) {
|
|
||||||
lexer->result_symbol = ENCAPSED_STRING_CHARS_AFTER_VARIABLE;
|
|
||||||
return scan_encapsed_part_string(lexer, /* is_after_variable */ true, /* is_heredoc */ false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid_symbols[ENCAPSED_STRING_CHARS]) {
|
|
||||||
lexer->result_symbol = ENCAPSED_STRING_CHARS;
|
|
||||||
return scan_encapsed_part_string(lexer, /* is_after_variable */ false, /* is_heredoc */ false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid_symbols[ENCAPSED_STRING_CHARS_AFTER_VARIABLE_HEREDOC]) {
|
|
||||||
lexer->result_symbol = ENCAPSED_STRING_CHARS_AFTER_VARIABLE_HEREDOC;
|
|
||||||
return scan_encapsed_part_string(lexer, /* is_after_variable */ true, /* is_heredoc */ true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid_symbols[ENCAPSED_STRING_CHARS_HEREDOC]) {
|
|
||||||
lexer->result_symbol = ENCAPSED_STRING_CHARS_HEREDOC;
|
|
||||||
return scan_encapsed_part_string(lexer, /* is_after_variable */ false, /* is_heredoc */ true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid_symbols[NOWDOC_STRING]) {
|
|
||||||
lexer->result_symbol = NOWDOC_STRING;
|
|
||||||
return scan_nowdoc_string(lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid_symbols[HEREDOC_END]) {
|
|
||||||
lexer->result_symbol = HEREDOC_END;
|
|
||||||
if (open_heredocs.empty()) return false;
|
|
||||||
|
|
||||||
Heredoc heredoc = open_heredocs.back();
|
|
||||||
|
|
||||||
while (iswspace(lexer->lookahead)) {
|
|
||||||
advance(lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (heredoc.word != scan_heredoc_word(lexer)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lexer->mark_end(lexer);
|
|
||||||
open_heredocs.pop_back();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!scan_whitespace(lexer)) return false;
|
|
||||||
|
|
||||||
if (valid_symbols[EOF_TOKEN] && lexer->eof(lexer)) {
|
|
||||||
lexer->result_symbol = EOF_TOKEN;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (valid_symbols[HEREDOC_START]) {
|
|
||||||
lexer->result_symbol = HEREDOC_START;
|
|
||||||
Heredoc heredoc;
|
|
||||||
|
|
||||||
while (iswspace(lexer->lookahead)) {
|
|
||||||
skip(lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
heredoc.word = scan_heredoc_word(lexer);
|
|
||||||
if (heredoc.word.empty()) return false;
|
|
||||||
lexer->mark_end(lexer);
|
|
||||||
|
|
||||||
open_heredocs.push_back(heredoc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid_symbols[AUTOMATIC_SEMICOLON]) {
|
|
||||||
lexer->result_symbol = AUTOMATIC_SEMICOLON;
|
|
||||||
|
|
||||||
if (lexer->lookahead != '?') return false;
|
|
||||||
|
|
||||||
advance(lexer);
|
|
||||||
|
|
||||||
return lexer->lookahead == '>';
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
void *tree_sitter_php_external_scanner_create() {
|
|
||||||
return new Scanner();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned tree_sitter_php_external_scanner_serialize(void *payload, char *buffer) {
|
|
||||||
Scanner *scanner = static_cast<Scanner *>(payload);
|
|
||||||
return scanner->serialize(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tree_sitter_php_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) {
|
|
||||||
Scanner *scanner = static_cast<Scanner *>(payload);
|
|
||||||
scanner->deserialize(buffer, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tree_sitter_php_external_scanner_destroy(void *payload) {
|
|
||||||
Scanner *scanner = static_cast<Scanner *>(payload);
|
|
||||||
delete scanner;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tree_sitter_php_external_scanner_scan(void *payload, TSLexer *lexer,
|
|
||||||
const bool *valid_symbols) {
|
|
||||||
|
|
||||||
Scanner *scanner = static_cast<Scanner *>(payload);
|
|
||||||
return scanner->scan(lexer, valid_symbols);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tree_sitter_php_external_scanner_reset(void *p) {}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,223 +0,0 @@
|
|||||||
#ifndef TREE_SITTER_PARSER_H_
|
|
||||||
#define TREE_SITTER_PARSER_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define ts_builtin_sym_error ((TSSymbol)-1)
|
|
||||||
#define ts_builtin_sym_end 0
|
|
||||||
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
|
|
||||||
|
|
||||||
typedef uint16_t TSStateId;
|
|
||||||
|
|
||||||
#ifndef TREE_SITTER_API_H_
|
|
||||||
typedef uint16_t TSSymbol;
|
|
||||||
typedef uint16_t TSFieldId;
|
|
||||||
typedef struct TSLanguage TSLanguage;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
TSFieldId field_id;
|
|
||||||
uint8_t child_index;
|
|
||||||
bool inherited;
|
|
||||||
} TSFieldMapEntry;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t index;
|
|
||||||
uint16_t length;
|
|
||||||
} TSFieldMapSlice;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool visible;
|
|
||||||
bool named;
|
|
||||||
bool supertype;
|
|
||||||
} TSSymbolMetadata;
|
|
||||||
|
|
||||||
typedef struct TSLexer TSLexer;
|
|
||||||
|
|
||||||
struct TSLexer {
|
|
||||||
int32_t lookahead;
|
|
||||||
TSSymbol result_symbol;
|
|
||||||
void (*advance)(TSLexer *, bool);
|
|
||||||
void (*mark_end)(TSLexer *);
|
|
||||||
uint32_t (*get_column)(TSLexer *);
|
|
||||||
bool (*is_at_included_range_start)(const TSLexer *);
|
|
||||||
bool (*eof)(const TSLexer *);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
TSParseActionTypeShift,
|
|
||||||
TSParseActionTypeReduce,
|
|
||||||
TSParseActionTypeAccept,
|
|
||||||
TSParseActionTypeRecover,
|
|
||||||
} TSParseActionType;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
uint8_t type;
|
|
||||||
TSStateId state;
|
|
||||||
bool extra;
|
|
||||||
bool repetition;
|
|
||||||
} shift;
|
|
||||||
struct {
|
|
||||||
uint8_t type;
|
|
||||||
uint8_t child_count;
|
|
||||||
TSSymbol symbol;
|
|
||||||
int16_t dynamic_precedence;
|
|
||||||
uint16_t production_id;
|
|
||||||
} reduce;
|
|
||||||
uint8_t type;
|
|
||||||
} TSParseAction;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint16_t lex_state;
|
|
||||||
uint16_t external_lex_state;
|
|
||||||
} TSLexMode;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
TSParseAction action;
|
|
||||||
struct {
|
|
||||||
uint8_t count;
|
|
||||||
bool reusable;
|
|
||||||
} entry;
|
|
||||||
} TSParseActionEntry;
|
|
||||||
|
|
||||||
struct TSLanguage {
|
|
||||||
uint32_t version;
|
|
||||||
uint32_t symbol_count;
|
|
||||||
uint32_t alias_count;
|
|
||||||
uint32_t token_count;
|
|
||||||
uint32_t external_token_count;
|
|
||||||
uint32_t state_count;
|
|
||||||
uint32_t large_state_count;
|
|
||||||
uint32_t production_id_count;
|
|
||||||
uint32_t field_count;
|
|
||||||
uint16_t max_alias_sequence_length;
|
|
||||||
const uint16_t *parse_table;
|
|
||||||
const uint16_t *small_parse_table;
|
|
||||||
const uint32_t *small_parse_table_map;
|
|
||||||
const TSParseActionEntry *parse_actions;
|
|
||||||
const char * const *symbol_names;
|
|
||||||
const char * const *field_names;
|
|
||||||
const TSFieldMapSlice *field_map_slices;
|
|
||||||
const TSFieldMapEntry *field_map_entries;
|
|
||||||
const TSSymbolMetadata *symbol_metadata;
|
|
||||||
const TSSymbol *public_symbol_map;
|
|
||||||
const uint16_t *alias_map;
|
|
||||||
const TSSymbol *alias_sequences;
|
|
||||||
const TSLexMode *lex_modes;
|
|
||||||
bool (*lex_fn)(TSLexer *, TSStateId);
|
|
||||||
bool (*keyword_lex_fn)(TSLexer *, TSStateId);
|
|
||||||
TSSymbol keyword_capture_token;
|
|
||||||
struct {
|
|
||||||
const bool *states;
|
|
||||||
const TSSymbol *symbol_map;
|
|
||||||
void *(*create)(void);
|
|
||||||
void (*destroy)(void *);
|
|
||||||
bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
|
|
||||||
unsigned (*serialize)(void *, char *);
|
|
||||||
void (*deserialize)(void *, const char *, unsigned);
|
|
||||||
} external_scanner;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Lexer Macros
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define START_LEXER() \
|
|
||||||
bool result = false; \
|
|
||||||
bool skip = false; \
|
|
||||||
bool eof = false; \
|
|
||||||
int32_t lookahead; \
|
|
||||||
goto start; \
|
|
||||||
next_state: \
|
|
||||||
lexer->advance(lexer, skip); \
|
|
||||||
start: \
|
|
||||||
skip = false; \
|
|
||||||
lookahead = lexer->lookahead;
|
|
||||||
|
|
||||||
#define ADVANCE(state_value) \
|
|
||||||
{ \
|
|
||||||
state = state_value; \
|
|
||||||
goto next_state; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SKIP(state_value) \
|
|
||||||
{ \
|
|
||||||
skip = true; \
|
|
||||||
state = state_value; \
|
|
||||||
goto next_state; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ACCEPT_TOKEN(symbol_value) \
|
|
||||||
result = true; \
|
|
||||||
lexer->result_symbol = symbol_value; \
|
|
||||||
lexer->mark_end(lexer);
|
|
||||||
|
|
||||||
#define END_STATE() return result;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parse Table Macros
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SMALL_STATE(id) id - LARGE_STATE_COUNT
|
|
||||||
|
|
||||||
#define STATE(id) id
|
|
||||||
|
|
||||||
#define ACTIONS(id) id
|
|
||||||
|
|
||||||
#define SHIFT(state_value) \
|
|
||||||
{{ \
|
|
||||||
.shift = { \
|
|
||||||
.type = TSParseActionTypeShift, \
|
|
||||||
.state = state_value \
|
|
||||||
} \
|
|
||||||
}}
|
|
||||||
|
|
||||||
#define SHIFT_REPEAT(state_value) \
|
|
||||||
{{ \
|
|
||||||
.shift = { \
|
|
||||||
.type = TSParseActionTypeShift, \
|
|
||||||
.state = state_value, \
|
|
||||||
.repetition = true \
|
|
||||||
} \
|
|
||||||
}}
|
|
||||||
|
|
||||||
#define SHIFT_EXTRA() \
|
|
||||||
{{ \
|
|
||||||
.shift = { \
|
|
||||||
.type = TSParseActionTypeShift, \
|
|
||||||
.extra = true \
|
|
||||||
} \
|
|
||||||
}}
|
|
||||||
|
|
||||||
#define REDUCE(symbol_val, child_count_val, ...) \
|
|
||||||
{{ \
|
|
||||||
.reduce = { \
|
|
||||||
.type = TSParseActionTypeReduce, \
|
|
||||||
.symbol = symbol_val, \
|
|
||||||
.child_count = child_count_val, \
|
|
||||||
__VA_ARGS__ \
|
|
||||||
}, \
|
|
||||||
}}
|
|
||||||
|
|
||||||
#define RECOVER() \
|
|
||||||
{{ \
|
|
||||||
.type = TSParseActionTypeRecover \
|
|
||||||
}}
|
|
||||||
|
|
||||||
#define ACCEPT_INPUT() \
|
|
||||||
{{ \
|
|
||||||
.type = TSParseActionTypeAccept \
|
|
||||||
}}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // TREE_SITTER_PARSER_H_
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
=========================================
|
|
||||||
#131: Parse error when using self as constant
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
define('self', 'value');
|
|
||||||
var_dump(self);
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(expression_statement
|
|
||||||
(function_call_expression
|
|
||||||
function: (name)
|
|
||||||
arguments: (arguments
|
|
||||||
(argument (string (string_value)))
|
|
||||||
(argument (string (string_value)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(expression_statement
|
|
||||||
(function_call_expression
|
|
||||||
function: (name)
|
|
||||||
arguments: (arguments (argument (name)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
=========================================
|
|
||||||
#133: Incorrect precedence for error supression operator
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
@trigger_error("a") && trigger_error("b");
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(expression_statement
|
|
||||||
(binary_expression
|
|
||||||
left: (unary_op_expression
|
|
||||||
(function_call_expression
|
|
||||||
function: (name)
|
|
||||||
arguments: (arguments
|
|
||||||
(argument
|
|
||||||
(encapsed_string
|
|
||||||
(string_value)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
right: (function_call_expression
|
|
||||||
function: (name)
|
|
||||||
arguments: (arguments
|
|
||||||
(argument
|
|
||||||
(encapsed_string
|
|
||||||
(string_value)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
@ -1,770 +0,0 @@
|
|||||||
=========================================
|
|
||||||
Abstract class
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
abstract class A {
|
|
||||||
public function a() {}
|
|
||||||
abstract public function b();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(class_declaration
|
|
||||||
(abstract_modifier)
|
|
||||||
(name)
|
|
||||||
(declaration_list
|
|
||||||
(method_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(name)
|
|
||||||
(formal_parameters)
|
|
||||||
(compound_statement)
|
|
||||||
)
|
|
||||||
(method_declaration
|
|
||||||
(abstract_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(name)
|
|
||||||
(formal_parameters)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
=========================================
|
|
||||||
Anonymous classes
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
new class {
|
|
||||||
public function test() {}
|
|
||||||
};
|
|
||||||
new class extends A implements B, C {};
|
|
||||||
new class() {
|
|
||||||
public $foo;
|
|
||||||
};
|
|
||||||
new class($a, $b) extends A {
|
|
||||||
use T;
|
|
||||||
};
|
|
||||||
|
|
||||||
class A {
|
|
||||||
public function test() {
|
|
||||||
return new class($this) extends A {
|
|
||||||
const A = 'B';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(expression_statement
|
|
||||||
(object_creation_expression
|
|
||||||
(declaration_list
|
|
||||||
(method_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(name)
|
|
||||||
(formal_parameters)
|
|
||||||
(compound_statement)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(expression_statement
|
|
||||||
(object_creation_expression
|
|
||||||
(base_clause
|
|
||||||
(name)
|
|
||||||
)
|
|
||||||
(class_interface_clause
|
|
||||||
(name)
|
|
||||||
(name)
|
|
||||||
)
|
|
||||||
(declaration_list)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(expression_statement
|
|
||||||
(object_creation_expression
|
|
||||||
(arguments)
|
|
||||||
(declaration_list
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(property_element
|
|
||||||
(variable_name (name))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(expression_statement
|
|
||||||
(object_creation_expression
|
|
||||||
(arguments
|
|
||||||
(argument
|
|
||||||
(variable_name (name))
|
|
||||||
)
|
|
||||||
(argument
|
|
||||||
(variable_name (name))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(base_clause
|
|
||||||
(name)
|
|
||||||
)
|
|
||||||
(declaration_list
|
|
||||||
(use_declaration
|
|
||||||
(name)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(class_declaration
|
|
||||||
(name)
|
|
||||||
(declaration_list
|
|
||||||
(method_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(name)
|
|
||||||
(formal_parameters)
|
|
||||||
(compound_statement
|
|
||||||
(return_statement
|
|
||||||
(object_creation_expression
|
|
||||||
(arguments (argument (variable_name (name))))
|
|
||||||
(base_clause (name))
|
|
||||||
(declaration_list
|
|
||||||
(const_declaration
|
|
||||||
(const_element (name) (string (string_value)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
=========================================
|
|
||||||
Conditional class definition
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
if (true) {
|
|
||||||
class A {}
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(if_statement
|
|
||||||
(parenthesized_expression (boolean))
|
|
||||||
(compound_statement
|
|
||||||
(class_declaration
|
|
||||||
(name)
|
|
||||||
(declaration_list)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
=========================================
|
|
||||||
Class constant modifiers
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
class Foo {
|
|
||||||
const A = 1;
|
|
||||||
public const B = 2;
|
|
||||||
protected const C = 3;
|
|
||||||
private const D = 4;
|
|
||||||
final const E = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(class_declaration
|
|
||||||
(name)
|
|
||||||
(declaration_list
|
|
||||||
(const_declaration
|
|
||||||
(const_element (name) (integer))
|
|
||||||
)
|
|
||||||
(const_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(const_element (name) (integer))
|
|
||||||
)
|
|
||||||
(const_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(const_element (name) (integer))
|
|
||||||
)
|
|
||||||
(const_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(const_element (name) (integer))
|
|
||||||
)
|
|
||||||
(const_declaration
|
|
||||||
(final_modifier)
|
|
||||||
(const_element (name) (integer))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
=========================================
|
|
||||||
Final class
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
final class A {}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(class_declaration
|
|
||||||
(final_modifier)
|
|
||||||
(name)
|
|
||||||
(declaration_list)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
=========================================
|
|
||||||
Implicitly public properties and methods
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
abstract class A {
|
|
||||||
var $a;
|
|
||||||
static $b;
|
|
||||||
abstract function c();
|
|
||||||
final function d() {}
|
|
||||||
static function e() {}
|
|
||||||
final static function f() {}
|
|
||||||
function g() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(class_declaration
|
|
||||||
(abstract_modifier)
|
|
||||||
(name)
|
|
||||||
(declaration_list
|
|
||||||
(property_declaration
|
|
||||||
(var_modifier)
|
|
||||||
(property_element (variable_name (name)))
|
|
||||||
)
|
|
||||||
(property_declaration
|
|
||||||
(static_modifier)
|
|
||||||
(property_element (variable_name (name)))
|
|
||||||
)
|
|
||||||
(method_declaration
|
|
||||||
(abstract_modifier)
|
|
||||||
(name)
|
|
||||||
(formal_parameters)
|
|
||||||
)
|
|
||||||
(method_declaration
|
|
||||||
(final_modifier)
|
|
||||||
(name)
|
|
||||||
(formal_parameters)
|
|
||||||
(compound_statement)
|
|
||||||
)
|
|
||||||
(method_declaration
|
|
||||||
(static_modifier)
|
|
||||||
(name)
|
|
||||||
(formal_parameters)
|
|
||||||
(compound_statement)
|
|
||||||
)
|
|
||||||
(method_declaration
|
|
||||||
(final_modifier)
|
|
||||||
(static_modifier)
|
|
||||||
(name)
|
|
||||||
(formal_parameters)
|
|
||||||
(compound_statement)
|
|
||||||
)
|
|
||||||
(method_declaration
|
|
||||||
(name)
|
|
||||||
(formal_parameters)
|
|
||||||
(compound_statement)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
=========================================
|
|
||||||
Property Types
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
class A {
|
|
||||||
public string $a;
|
|
||||||
protected static D $b;
|
|
||||||
private ?float $c;
|
|
||||||
private $d;
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(class_declaration
|
|
||||||
name: (name)
|
|
||||||
body: (declaration_list
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
type: (union_type (primitive_type))
|
|
||||||
(property_element (variable_name (name)))
|
|
||||||
)
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(static_modifier)
|
|
||||||
type: (union_type (named_type (name)))
|
|
||||||
(property_element (variable_name (name)))
|
|
||||||
)
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
type: (union_type (optional_type (primitive_type)))
|
|
||||||
(property_element (variable_name (name)))
|
|
||||||
)
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(property_element (variable_name (name)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
=========================================
|
|
||||||
Constructor Property Promotion
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
class Point {
|
|
||||||
public function __construct(
|
|
||||||
public float $x = 0.0,
|
|
||||||
float $y = 0.0,
|
|
||||||
private float $z = 0.0
|
|
||||||
) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(class_declaration
|
|
||||||
name: (name)
|
|
||||||
body: (declaration_list
|
|
||||||
(method_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
name: (name)
|
|
||||||
parameters: (formal_parameters
|
|
||||||
(property_promotion_parameter
|
|
||||||
visibility: (visibility_modifier)
|
|
||||||
type: (union_type
|
|
||||||
(primitive_type)
|
|
||||||
)
|
|
||||||
name: (variable_name (name))
|
|
||||||
default_value: (float)
|
|
||||||
)
|
|
||||||
(simple_parameter
|
|
||||||
type: (union_type (primitive_type))
|
|
||||||
name: (variable_name (name))
|
|
||||||
default_value: (float)
|
|
||||||
)
|
|
||||||
(property_promotion_parameter
|
|
||||||
visibility: (visibility_modifier)
|
|
||||||
type: (union_type (primitive_type))
|
|
||||||
name: (variable_name (name))
|
|
||||||
default_value: (float)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
body: (compound_statement)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
Readonly properties
|
|
||||||
================================================================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
class A {
|
|
||||||
private readonly int $pria;
|
|
||||||
private readonly float $prfa;
|
|
||||||
private readonly mixed $prma;
|
|
||||||
private readonly string $prsa;
|
|
||||||
private readonly object $proa;
|
|
||||||
readonly private int $rpia;
|
|
||||||
readonly private float $rpfa;
|
|
||||||
readonly private mixed $rpma;
|
|
||||||
readonly private string $rpsa;
|
|
||||||
readonly private object $rpoa;
|
|
||||||
|
|
||||||
protected readonly int $oria;
|
|
||||||
protected readonly float $orfa;
|
|
||||||
protected readonly mixed $orma;
|
|
||||||
protected readonly string $orsa;
|
|
||||||
protected readonly object $oroa;
|
|
||||||
readonly protected int $roia;
|
|
||||||
readonly protected float $rofa;
|
|
||||||
readonly protected mixed $roma;
|
|
||||||
readonly protected string $rosa;
|
|
||||||
readonly protected object $rooa;
|
|
||||||
|
|
||||||
public readonly int $uria;
|
|
||||||
public readonly float $urfa;
|
|
||||||
public readonly mixed $urma;
|
|
||||||
public readonly string $ursa;
|
|
||||||
public readonly object $uroa;
|
|
||||||
readonly public int $ruia;
|
|
||||||
readonly public float $rufa;
|
|
||||||
readonly public mixed $ruma;
|
|
||||||
readonly public string $rusa;
|
|
||||||
readonly public object $ruoa;
|
|
||||||
|
|
||||||
readonly int $ria;
|
|
||||||
readonly float $rfa;
|
|
||||||
readonly mixed $rma;
|
|
||||||
ReAdOnLy string $rsa;
|
|
||||||
READONLY object $roa;
|
|
||||||
}
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(class_declaration
|
|
||||||
(name)
|
|
||||||
(declaration_list
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(named_type
|
|
||||||
(name)))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(named_type
|
|
||||||
(name)))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(named_type
|
|
||||||
(name)))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(named_type
|
|
||||||
(name)))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(named_type
|
|
||||||
(name)))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(visibility_modifier)
|
|
||||||
(union_type
|
|
||||||
(named_type
|
|
||||||
(name)))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name))))
|
|
||||||
(property_declaration
|
|
||||||
(readonly_modifier)
|
|
||||||
(union_type
|
|
||||||
(named_type
|
|
||||||
(name)))
|
|
||||||
(property_element
|
|
||||||
(variable_name
|
|
||||||
(name)))))))
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
Constructor property promotion with readonly modifier
|
|
||||||
================================================================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
class Point {
|
|
||||||
public function __construct(
|
|
||||||
public $x,
|
|
||||||
protected readonly $y,
|
|
||||||
private readonly int $z,
|
|
||||||
) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(class_declaration
|
|
||||||
name: (name)
|
|
||||||
body: (declaration_list
|
|
||||||
(method_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
name: (name)
|
|
||||||
parameters: (formal_parameters
|
|
||||||
(property_promotion_parameter
|
|
||||||
visibility: (visibility_modifier)
|
|
||||||
name: (variable_name (name)))
|
|
||||||
(property_promotion_parameter
|
|
||||||
visibility: (visibility_modifier)
|
|
||||||
readonly: (readonly_modifier)
|
|
||||||
name: (variable_name (name)))
|
|
||||||
(property_promotion_parameter
|
|
||||||
visibility: (visibility_modifier)
|
|
||||||
readonly: (readonly_modifier)
|
|
||||||
type: (union_type (primitive_type))
|
|
||||||
name: (variable_name (name))))
|
|
||||||
body: (compound_statement)))))
|
|
||||||
@ -1,706 +0,0 @@
|
|||||||
=========================================
|
|
||||||
Interface declarations
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
interface ThrowableInterface {
|
|
||||||
public function getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
class Exception_foo implements ThrowableInterface {
|
|
||||||
public $foo = "foo";
|
|
||||||
|
|
||||||
public function getMessage() {
|
|
||||||
return $this->foo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(interface_declaration
|
|
||||||
name: (name)
|
|
||||||
body: (declaration_list
|
|
||||||
(method_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
name: (name)
|
|
||||||
parameters: (formal_parameters))))
|
|
||||||
(class_declaration
|
|
||||||
name: (name)
|
|
||||||
(class_interface_clause (name))
|
|
||||||
body: (declaration_list
|
|
||||||
(property_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(property_element (variable_name (name)) (property_initializer (encapsed_string (string_value)))))
|
|
||||||
(method_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
name: (name)
|
|
||||||
parameters: (formal_parameters)
|
|
||||||
body: (compound_statement
|
|
||||||
(return_statement (member_access_expression
|
|
||||||
object: (variable_name (name))
|
|
||||||
name: (name))))))))
|
|
||||||
|
|
||||||
==========================
|
|
||||||
Use declarations
|
|
||||||
==========================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
trait AbstractTrait
|
|
||||||
{
|
|
||||||
use LoggerAwareTrait;
|
|
||||||
use LoggerAwareTrait, OtherTrait {}
|
|
||||||
use LoggerAwareTrait, OtherTrait;
|
|
||||||
}
|
|
||||||
|
|
||||||
class AbstractCache
|
|
||||||
{
|
|
||||||
use AbstractTrait {
|
|
||||||
deleteItems as private;
|
|
||||||
AbstractTrait::deleteItem as delete;
|
|
||||||
AbstractTrait::hasItem as has;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(trait_declaration
|
|
||||||
(name)
|
|
||||||
(declaration_list
|
|
||||||
(use_declaration (name))
|
|
||||||
(use_declaration (name) (name) (use_list))
|
|
||||||
(use_declaration (name) (name))))
|
|
||||||
(class_declaration
|
|
||||||
(name)
|
|
||||||
(declaration_list
|
|
||||||
(use_declaration
|
|
||||||
(name)
|
|
||||||
(use_list
|
|
||||||
(use_as_clause (name) (visibility_modifier))
|
|
||||||
(use_as_clause (class_constant_access_expression (name) (name)) (name))
|
|
||||||
(use_as_clause (class_constant_access_expression (name) (name)) (name)))))))
|
|
||||||
|
|
||||||
==========================
|
|
||||||
Namespace names in namespaces
|
|
||||||
==========================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Be \ ta {
|
|
||||||
class A {}
|
|
||||||
class B {}
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(namespace_definition
|
|
||||||
name: (namespace_name (name) (name))
|
|
||||||
body: (compound_statement
|
|
||||||
(class_declaration
|
|
||||||
name: (name)
|
|
||||||
body: (declaration_list))
|
|
||||||
(class_declaration
|
|
||||||
name: (name)
|
|
||||||
body: (declaration_list)))))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
Class declarations
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
class foo {
|
|
||||||
function __construct($name) {
|
|
||||||
$GLOBALS['List']= &$this;
|
|
||||||
$this->Name = $name;
|
|
||||||
$GLOBALS['List']->echoName();
|
|
||||||
}
|
|
||||||
|
|
||||||
function echoName() {
|
|
||||||
$GLOBALS['names'][]=$this->Name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(class_declaration
|
|
||||||
name: (name)
|
|
||||||
body: (declaration_list
|
|
||||||
(method_declaration
|
|
||||||
name: (name)
|
|
||||||
parameters: (formal_parameters
|
|
||||||
(simple_parameter
|
|
||||||
name: (variable_name (name))))
|
|
||||||
body: (compound_statement
|
|
||||||
(expression_statement (reference_assignment_expression
|
|
||||||
left: (subscript_expression (variable_name (name)) (string (string_value)))
|
|
||||||
right: (variable_name (name))))
|
|
||||||
(expression_statement (assignment_expression
|
|
||||||
left: (member_access_expression
|
|
||||||
object: (variable_name (name))
|
|
||||||
name: (name))
|
|
||||||
right: (variable_name (name))))
|
|
||||||
(expression_statement (member_call_expression
|
|
||||||
object: (subscript_expression (variable_name (name)) (string (string_value)))
|
|
||||||
name: (name)
|
|
||||||
arguments: (arguments)))))
|
|
||||||
(method_declaration
|
|
||||||
name: (name)
|
|
||||||
parameters: (formal_parameters)
|
|
||||||
body: (compound_statement
|
|
||||||
(expression_statement (assignment_expression
|
|
||||||
left: (subscript_expression (subscript_expression (variable_name (name)) (string (string_value))))
|
|
||||||
right: (member_access_expression
|
|
||||||
object: (variable_name (name))
|
|
||||||
name: (name)))))))))
|
|
||||||
|
|
||||||
========================================
|
|
||||||
Class declarations with base classes
|
|
||||||
========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
class A extends B {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(class_declaration
|
|
||||||
name: (name)
|
|
||||||
(base_clause (name))
|
|
||||||
body: (declaration_list)))
|
|
||||||
|
|
||||||
==========================
|
|
||||||
Function parameters
|
|
||||||
==========================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
function test(int $a, string ...$b)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(function_definition
|
|
||||||
name: (name)
|
|
||||||
parameters: (formal_parameters
|
|
||||||
(simple_parameter
|
|
||||||
type: (union_type (primitive_type))
|
|
||||||
name: (variable_name (name)))
|
|
||||||
(variadic_parameter
|
|
||||||
type: (union_type (primitive_type))
|
|
||||||
name: (variable_name (name))))
|
|
||||||
body: (compound_statement)))
|
|
||||||
|
|
||||||
====================================
|
|
||||||
Functions with default parameters
|
|
||||||
====================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
function a($arg = self::bar) {
|
|
||||||
echo $arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(function_definition
|
|
||||||
(name)
|
|
||||||
(formal_parameters
|
|
||||||
(simple_parameter
|
|
||||||
(variable_name (name))
|
|
||||||
(class_constant_access_expression (relative_scope) (name))))
|
|
||||||
(compound_statement (echo_statement (variable_name (name))))))
|
|
||||||
|
|
||||||
========================================================================
|
|
||||||
Static variables in functions
|
|
||||||
========================================================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
function blah()
|
|
||||||
{
|
|
||||||
static $hey=0, $yo=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(function_definition
|
|
||||||
(name)
|
|
||||||
(formal_parameters)
|
|
||||||
(compound_statement
|
|
||||||
(function_static_declaration
|
|
||||||
(static_variable_declaration (variable_name (name)) (integer))
|
|
||||||
(static_variable_declaration (variable_name (name)) (integer))))))
|
|
||||||
|
|
||||||
=========================================
|
|
||||||
Defining Constants
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
define("CONSTANT", "Hello world.");
|
|
||||||
const CONSTANT = 'Hello World';
|
|
||||||
const ANOTHER_CONST = CONSTANT.'; Goodbye World';
|
|
||||||
const ANIMALS = array('dog', 'cat', 'bird');
|
|
||||||
define('ANIMALS', array(
|
|
||||||
'dog',
|
|
||||||
'cat',
|
|
||||||
'bird'
|
|
||||||
));
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(expression_statement
|
|
||||||
(function_call_expression
|
|
||||||
(name)
|
|
||||||
(arguments
|
|
||||||
(argument (encapsed_string (string_value)))
|
|
||||||
(argument (encapsed_string (string_value)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(const_declaration
|
|
||||||
(const_element
|
|
||||||
(name)
|
|
||||||
(string (string_value))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(const_declaration
|
|
||||||
(const_element
|
|
||||||
(name)
|
|
||||||
(binary_expression
|
|
||||||
(name)
|
|
||||||
(string (string_value))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(const_declaration
|
|
||||||
(const_element
|
|
||||||
(name)
|
|
||||||
(array_creation_expression
|
|
||||||
(array_element_initializer (string (string_value)))
|
|
||||||
(array_element_initializer (string (string_value)))
|
|
||||||
(array_element_initializer (string (string_value)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(expression_statement
|
|
||||||
(function_call_expression
|
|
||||||
(name)
|
|
||||||
(arguments
|
|
||||||
(argument (string (string_value)))
|
|
||||||
(argument
|
|
||||||
(array_creation_expression
|
|
||||||
(array_element_initializer (string (string_value)))
|
|
||||||
(array_element_initializer (string (string_value)))
|
|
||||||
(array_element_initializer (string (string_value)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
=======================================
|
|
||||||
Attributes
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
#[Test]
|
|
||||||
function a(#[Test] $a) {
|
|
||||||
$c;
|
|
||||||
}
|
|
||||||
|
|
||||||
class PostsController
|
|
||||||
{
|
|
||||||
#[Test]
|
|
||||||
const CONSTANT = 'constant value';
|
|
||||||
|
|
||||||
#[Test]
|
|
||||||
private string $a = '';
|
|
||||||
|
|
||||||
#[Route("/api/posts/{id}", ["GET"])]
|
|
||||||
public function get(#[Test] $id) { /* ... */ }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[MyAttribute]
|
|
||||||
#[\MyExample\MyAttribute]
|
|
||||||
#[MyAttribute(1234)]
|
|
||||||
#[MyAttribute(MyAttribute::VALUE)]
|
|
||||||
#[MyAttribute(array("key" => "value"))]
|
|
||||||
#[MyAttribute(100 + 200)]
|
|
||||||
class Thing
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
new #[ExampleAttribute] class() {};
|
|
||||||
#[ExampleAttribute] fn($x) => $x;
|
|
||||||
$baz = #[ExampleAttribute] function($x) {return $x;};
|
|
||||||
|
|
||||||
class A {
|
|
||||||
#[\Assert\All(
|
|
||||||
new \Assert\NotNull,
|
|
||||||
new \Assert\Length(min: 5))
|
|
||||||
]
|
|
||||||
public string $name = '';
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[
|
|
||||||
A1,
|
|
||||||
A2(),
|
|
||||||
A3(0),
|
|
||||||
A4(x: 1),
|
|
||||||
]
|
|
||||||
function a() {
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
|
|
||||||
(function_definition
|
|
||||||
attributes: (attribute_list (attribute_group (attribute (name))))
|
|
||||||
name: (name)
|
|
||||||
parameters: (formal_parameters
|
|
||||||
(simple_parameter
|
|
||||||
attributes: (attribute_list
|
|
||||||
(attribute_group (attribute (name)))
|
|
||||||
)
|
|
||||||
name: (variable_name (name))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
body: (compound_statement (expression_statement (variable_name (name))))
|
|
||||||
)
|
|
||||||
|
|
||||||
(class_declaration
|
|
||||||
name: (name)
|
|
||||||
body: (declaration_list
|
|
||||||
(const_declaration
|
|
||||||
attributes: (attribute_list (attribute_group (attribute (name))))
|
|
||||||
(const_element (name) (string (string_value)))
|
|
||||||
)
|
|
||||||
|
|
||||||
(property_declaration
|
|
||||||
attributes: (attribute_list (attribute_group (attribute (name))))
|
|
||||||
(visibility_modifier)
|
|
||||||
type: (union_type (primitive_type))
|
|
||||||
(property_element (variable_name (name))
|
|
||||||
(property_initializer (string (string_value)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(method_declaration
|
|
||||||
attributes: (attribute_list
|
|
||||||
(attribute_group
|
|
||||||
(attribute
|
|
||||||
(name)
|
|
||||||
parameters: (arguments
|
|
||||||
(argument (encapsed_string (string_value)))
|
|
||||||
(argument
|
|
||||||
(array_creation_expression
|
|
||||||
(array_element_initializer (encapsed_string (string_value)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(visibility_modifier)
|
|
||||||
name: (name)
|
|
||||||
parameters: (formal_parameters
|
|
||||||
(simple_parameter
|
|
||||||
attributes: (attribute_list (attribute_group (attribute (name))))
|
|
||||||
name: (variable_name (name))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
body: (compound_statement (comment))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(class_declaration
|
|
||||||
attributes: (attribute_list
|
|
||||||
(attribute_group
|
|
||||||
(attribute (name))
|
|
||||||
)
|
|
||||||
(attribute_group
|
|
||||||
(attribute
|
|
||||||
(qualified_name
|
|
||||||
(namespace_name_as_prefix
|
|
||||||
(namespace_name (name))
|
|
||||||
)
|
|
||||||
(name)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(attribute_group
|
|
||||||
(attribute
|
|
||||||
(name)
|
|
||||||
parameters: (arguments (argument (integer)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(attribute_group
|
|
||||||
(attribute
|
|
||||||
(name)
|
|
||||||
parameters: (arguments
|
|
||||||
(argument
|
|
||||||
(class_constant_access_expression
|
|
||||||
(name)
|
|
||||||
(name)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(attribute_group
|
|
||||||
(attribute
|
|
||||||
(name)
|
|
||||||
parameters: (arguments
|
|
||||||
(argument
|
|
||||||
(array_creation_expression
|
|
||||||
(array_element_initializer
|
|
||||||
(encapsed_string (string_value))
|
|
||||||
(encapsed_string (string_value))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(attribute_group
|
|
||||||
(attribute
|
|
||||||
(name)
|
|
||||||
parameters: (arguments
|
|
||||||
(argument
|
|
||||||
(binary_expression
|
|
||||||
left: (integer)
|
|
||||||
right: (integer)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
name: (name)
|
|
||||||
body: (declaration_list)
|
|
||||||
)
|
|
||||||
(expression_statement
|
|
||||||
(object_creation_expression
|
|
||||||
attributes: (attribute_list (attribute_group (attribute (name))))
|
|
||||||
(arguments)
|
|
||||||
(declaration_list)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(expression_statement
|
|
||||||
(arrow_function
|
|
||||||
attributes: (attribute_list (attribute_group (attribute (name))))
|
|
||||||
parameters: (formal_parameters
|
|
||||||
(simple_parameter
|
|
||||||
name: (variable_name (name))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
body: (variable_name (name))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(expression_statement
|
|
||||||
(assignment_expression
|
|
||||||
left: (variable_name (name))
|
|
||||||
right: (anonymous_function_creation_expression
|
|
||||||
attributes: (attribute_list (attribute_group (attribute (name))))
|
|
||||||
parameters: (formal_parameters
|
|
||||||
(simple_parameter
|
|
||||||
name: (variable_name (name))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
body: (compound_statement
|
|
||||||
(return_statement
|
|
||||||
(variable_name (name))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(class_declaration
|
|
||||||
name: (name)
|
|
||||||
body: (declaration_list
|
|
||||||
(property_declaration
|
|
||||||
attributes: (attribute_list
|
|
||||||
(attribute_group
|
|
||||||
(attribute
|
|
||||||
(qualified_name
|
|
||||||
(namespace_name_as_prefix (namespace_name (name)))
|
|
||||||
(name)
|
|
||||||
)
|
|
||||||
parameters: (arguments
|
|
||||||
(argument
|
|
||||||
(object_creation_expression
|
|
||||||
(qualified_name
|
|
||||||
(namespace_name_as_prefix (namespace_name (name)))
|
|
||||||
(name)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(argument
|
|
||||||
(object_creation_expression
|
|
||||||
(qualified_name
|
|
||||||
(namespace_name_as_prefix (namespace_name (name)))
|
|
||||||
(name)
|
|
||||||
)
|
|
||||||
(arguments
|
|
||||||
(argument
|
|
||||||
name: (name)
|
|
||||||
(integer)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(visibility_modifier)
|
|
||||||
type: (union_type (primitive_type))
|
|
||||||
(property_element
|
|
||||||
(variable_name (name))
|
|
||||||
(property_initializer (string (string_value)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(function_definition
|
|
||||||
attributes: (attribute_list
|
|
||||||
(attribute_group
|
|
||||||
(attribute (name))
|
|
||||||
(attribute
|
|
||||||
(name)
|
|
||||||
parameters: (arguments)
|
|
||||||
)
|
|
||||||
(attribute
|
|
||||||
(name)
|
|
||||||
parameters: (arguments (argument (integer)))
|
|
||||||
)
|
|
||||||
(attribute
|
|
||||||
(name)
|
|
||||||
parameters: (arguments (argument name: (name) (integer)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
name: (name)
|
|
||||||
parameters: (formal_parameters)
|
|
||||||
body: (compound_statement)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
=======================================
|
|
||||||
Enums
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
enum A {}
|
|
||||||
enum B implements Bar, Baz {
|
|
||||||
}
|
|
||||||
enum C: int implements Bar {}
|
|
||||||
|
|
||||||
enum Suit: string
|
|
||||||
{
|
|
||||||
case Hearts = 'H';
|
|
||||||
case Diamonds;
|
|
||||||
case Clubs = 'C';
|
|
||||||
case Spades = 'S';
|
|
||||||
|
|
||||||
// Fulfills the interface contract.
|
|
||||||
public function color(): string {
|
|
||||||
return match($this) {
|
|
||||||
Suit::Hearts, Suit::Diamonds => 'Red',
|
|
||||||
Suit::Clubs, Suit::Spades => 'Black',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(enum_declaration
|
|
||||||
(name)
|
|
||||||
(enum_declaration_list)
|
|
||||||
)
|
|
||||||
(enum_declaration
|
|
||||||
(name)
|
|
||||||
(class_interface_clause
|
|
||||||
(name)
|
|
||||||
(name)
|
|
||||||
)
|
|
||||||
(enum_declaration_list)
|
|
||||||
)
|
|
||||||
(enum_declaration
|
|
||||||
(name)
|
|
||||||
(union_type (primitive_type))
|
|
||||||
(class_interface_clause (name))
|
|
||||||
(enum_declaration_list)
|
|
||||||
)
|
|
||||||
(enum_declaration
|
|
||||||
(name)
|
|
||||||
(union_type (primitive_type))
|
|
||||||
(enum_declaration_list
|
|
||||||
(enum_case (name) (string (string_value)))
|
|
||||||
(enum_case (name))
|
|
||||||
(enum_case (name) (string (string_value)))
|
|
||||||
(enum_case (name) (string (string_value)))
|
|
||||||
|
|
||||||
(comment)
|
|
||||||
|
|
||||||
(method_declaration
|
|
||||||
(visibility_modifier)
|
|
||||||
(name)
|
|
||||||
(formal_parameters)
|
|
||||||
(union_type (primitive_type))
|
|
||||||
(compound_statement
|
|
||||||
(return_statement
|
|
||||||
(match_expression
|
|
||||||
(parenthesized_expression
|
|
||||||
(variable_name (name))
|
|
||||||
)
|
|
||||||
(match_block
|
|
||||||
(match_conditional_expression
|
|
||||||
(match_condition_list
|
|
||||||
(class_constant_access_expression (name) (name))
|
|
||||||
(class_constant_access_expression (name) (name))
|
|
||||||
)
|
|
||||||
(string (string_value))
|
|
||||||
)
|
|
||||||
(match_conditional_expression
|
|
||||||
(match_condition_list
|
|
||||||
(class_constant_access_expression (name) (name))
|
|
||||||
(class_constant_access_expression (name) (name))
|
|
||||||
)
|
|
||||||
(string (string_value))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,188 +0,0 @@
|
|||||||
====================
|
|
||||||
no interpolated text
|
|
||||||
====================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
echo "hi";
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(echo_statement (encapsed_string (string_value))))
|
|
||||||
|
|
||||||
===============================
|
|
||||||
interpolated text at beginning
|
|
||||||
===============================
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<?php
|
|
||||||
echo "hi";
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(text)
|
|
||||||
(php_tag)
|
|
||||||
(echo_statement (encapsed_string (string_value))))
|
|
||||||
|
|
||||||
===============================
|
|
||||||
interpolated text at end
|
|
||||||
===============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
echo "hi";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(echo_statement (encapsed_string (string_value)))
|
|
||||||
(text_interpolation (text)))
|
|
||||||
|
|
||||||
===============================
|
|
||||||
interpolated text in middle
|
|
||||||
===============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
echo "hi";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
echo "bye";
|
|
||||||
?>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(echo_statement (encapsed_string (string_value)))
|
|
||||||
(text_interpolation
|
|
||||||
(text)
|
|
||||||
(php_tag))
|
|
||||||
(echo_statement (encapsed_string (string_value)))
|
|
||||||
(text_interpolation))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
short open tag: On
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?
|
|
||||||
echo "Used a short tag\n";
|
|
||||||
?>
|
|
||||||
Finished
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(echo_statement (encapsed_string (string_value) (escape_sequence)))
|
|
||||||
(text_interpolation (text)))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
short open tag: Off
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<div>one</div>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
$a = 'This gets echoed twice';
|
|
||||||
?>
|
|
||||||
|
|
||||||
<?= $a ?>
|
|
||||||
|
|
||||||
<div>two</div>
|
|
||||||
|
|
||||||
<? $b=3; ?>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
echo "{$b}";
|
|
||||||
?>
|
|
||||||
|
|
||||||
<?= "{$b}" ?>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(text)
|
|
||||||
(php_tag)
|
|
||||||
(expression_statement (assignment_expression (variable_name (name)) (string (string_value))))
|
|
||||||
(text_interpolation (php_tag))
|
|
||||||
(expression_statement (variable_name (name)))
|
|
||||||
(text_interpolation (text) (php_tag))
|
|
||||||
(expression_statement (assignment_expression (variable_name (name)) (integer)))
|
|
||||||
(text_interpolation (php_tag))
|
|
||||||
(echo_statement (encapsed_string (variable_name (name))))
|
|
||||||
(text_interpolation (php_tag))
|
|
||||||
(expression_statement (encapsed_string (variable_name (name))))
|
|
||||||
(text_interpolation))
|
|
||||||
|
|
||||||
======================
|
|
||||||
Single line php comment
|
|
||||||
======================
|
|
||||||
|
|
||||||
<ul class="foo"><?php // this is a comment ?></ul>
|
|
||||||
|
|
||||||
<?php
|
|
||||||
// foo?
|
|
||||||
// foo? bar?
|
|
||||||
echo "hi";
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(text)
|
|
||||||
(php_tag)
|
|
||||||
(comment)
|
|
||||||
(text_interpolation (text) (php_tag))
|
|
||||||
(comment)
|
|
||||||
(comment)
|
|
||||||
(echo_statement (encapsed_string (string_value))))
|
|
||||||
|
|
||||||
|
|
||||||
=======================================
|
|
||||||
Singel line comment without any content
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
# Check if PHP xml isn't compiled
|
|
||||||
#
|
|
||||||
if ( ! function_exists('xml_parser_create') ) {
|
|
||||||
echo $test;
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(comment)
|
|
||||||
(comment)
|
|
||||||
(if_statement
|
|
||||||
condition: (parenthesized_expression
|
|
||||||
(unary_op_expression
|
|
||||||
(function_call_expression
|
|
||||||
function: (name)
|
|
||||||
arguments: (arguments (argument (string (string_value))))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
body: (compound_statement (echo_statement (variable_name (name))))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
=====================================
|
|
||||||
Closing tags before the first PHP tag
|
|
||||||
=====================================
|
|
||||||
|
|
||||||
a ?> b <?php c;
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(text)
|
|
||||||
(php_tag)
|
|
||||||
(expression_statement
|
|
||||||
(name)))
|
|
||||||
@ -1,109 +0,0 @@
|
|||||||
========================
|
|
||||||
Booleans
|
|
||||||
========================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
True;
|
|
||||||
true;
|
|
||||||
TRUE;
|
|
||||||
false;
|
|
||||||
False;
|
|
||||||
FALSE;
|
|
||||||
?>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(expression_statement (boolean))
|
|
||||||
(expression_statement (boolean))
|
|
||||||
(expression_statement (boolean))
|
|
||||||
(expression_statement (boolean))
|
|
||||||
(expression_statement (boolean))
|
|
||||||
(expression_statement (boolean))
|
|
||||||
(text_interpolation))
|
|
||||||
|
|
||||||
==========================
|
|
||||||
Floats
|
|
||||||
==========================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
1.0;
|
|
||||||
1E432;
|
|
||||||
1.0E-3432;
|
|
||||||
1423.0E3432;
|
|
||||||
.5;
|
|
||||||
6.674_083e11;
|
|
||||||
107_925_284.88;
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(expression_statement (float))
|
|
||||||
(expression_statement (float))
|
|
||||||
(expression_statement (float))
|
|
||||||
(expression_statement (float))
|
|
||||||
(expression_statement (float))
|
|
||||||
(expression_statement (float))
|
|
||||||
(expression_statement (float))
|
|
||||||
)
|
|
||||||
|
|
||||||
==========================
|
|
||||||
Integers
|
|
||||||
==========================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
1234;
|
|
||||||
1_234_456;
|
|
||||||
0123;
|
|
||||||
0123_456;
|
|
||||||
0x1A;
|
|
||||||
0x1A_2B_3C;
|
|
||||||
0b111111111;
|
|
||||||
0b1111_1111_1111;
|
|
||||||
0o123;
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(expression_statement (integer))
|
|
||||||
(expression_statement (integer))
|
|
||||||
(expression_statement (integer))
|
|
||||||
(expression_statement (integer))
|
|
||||||
(expression_statement (integer))
|
|
||||||
(expression_statement (integer))
|
|
||||||
(expression_statement (integer))
|
|
||||||
(expression_statement (integer))
|
|
||||||
(expression_statement (integer))
|
|
||||||
)
|
|
||||||
|
|
||||||
============================
|
|
||||||
Testing string scanner confirmance
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php echo "\"\t\\'" . '\n\\\'a\\\b\\' ?>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(echo_statement (binary_expression (encapsed_string (escape_sequence) (escape_sequence) (escape_sequence) (string_value)) (string (string_value))))
|
|
||||||
(text_interpolation))
|
|
||||||
|
|
||||||
==========================
|
|
||||||
Shell command
|
|
||||||
==========================
|
|
||||||
<?php
|
|
||||||
`ls -la`;
|
|
||||||
`ls`;
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(expression_statement (shell_command_expression))
|
|
||||||
(expression_statement (shell_command_expression)))
|
|
||||||
@ -1,469 +0,0 @@
|
|||||||
==============================
|
|
||||||
If statements
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
if ($a > 0) {
|
|
||||||
echo "Yes";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($a==0) {
|
|
||||||
echo "bad";
|
|
||||||
} else {
|
|
||||||
echo "good";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($a==0) {
|
|
||||||
echo "bad";
|
|
||||||
} elseif ($a==3) {
|
|
||||||
echo "bad";
|
|
||||||
} else {
|
|
||||||
echo "good";
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(if_statement
|
|
||||||
condition: (parenthesized_expression (binary_expression
|
|
||||||
left: (variable_name (name))
|
|
||||||
right: (integer)))
|
|
||||||
body: (compound_statement (echo_statement (encapsed_string (string_value)))))
|
|
||||||
(if_statement
|
|
||||||
condition: (parenthesized_expression (binary_expression
|
|
||||||
left: (variable_name (name))
|
|
||||||
right: (integer)))
|
|
||||||
body: (compound_statement (echo_statement (encapsed_string (string_value))))
|
|
||||||
alternative: (else_clause
|
|
||||||
body: (compound_statement (echo_statement (encapsed_string (string_value))))))
|
|
||||||
(if_statement
|
|
||||||
condition: (parenthesized_expression (binary_expression
|
|
||||||
left: (variable_name (name))
|
|
||||||
right: (integer)))
|
|
||||||
body: (compound_statement (echo_statement (encapsed_string (string_value))))
|
|
||||||
alternative: (else_if_clause
|
|
||||||
condition: (parenthesized_expression (binary_expression
|
|
||||||
left: (variable_name (name))
|
|
||||||
right: (integer)))
|
|
||||||
body: (compound_statement (echo_statement (encapsed_string (string_value)))))
|
|
||||||
alternative: (else_clause
|
|
||||||
body: (compound_statement (echo_statement (encapsed_string (string_value)))))))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
Alternative if statements
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
if ($a) echo 1; else echo 0;
|
|
||||||
if ($a):
|
|
||||||
echo 1;
|
|
||||||
echo 2;
|
|
||||||
else:
|
|
||||||
echo 0;
|
|
||||||
endif;
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(if_statement
|
|
||||||
condition: (parenthesized_expression (variable_name (name)))
|
|
||||||
body: (echo_statement (integer))
|
|
||||||
alternative: (else_clause
|
|
||||||
body: (echo_statement (integer))))
|
|
||||||
(if_statement
|
|
||||||
condition: (parenthesized_expression (variable_name (name)))
|
|
||||||
body: (colon_block
|
|
||||||
(echo_statement (integer))
|
|
||||||
(echo_statement (integer)))
|
|
||||||
alternative: (else_clause
|
|
||||||
body: (colon_block
|
|
||||||
(echo_statement (integer))))))
|
|
||||||
|
|
||||||
====================================
|
|
||||||
Wordpress colon blocks
|
|
||||||
====================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
if ($post) :
|
|
||||||
?>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
if ( $open ) {
|
|
||||||
$attachment_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
<?php
|
|
||||||
else :
|
|
||||||
$post;
|
|
||||||
|
|
||||||
endif;
|
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(if_statement
|
|
||||||
condition: (parenthesized_expression (variable_name (name)))
|
|
||||||
body: (colon_block
|
|
||||||
(text_interpolation (php_tag))
|
|
||||||
(if_statement
|
|
||||||
condition: (parenthesized_expression (variable_name (name)))
|
|
||||||
body: (compound_statement (expression_statement (variable_name (name))))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(text_interpolation (php_tag))
|
|
||||||
alternative: (else_clause
|
|
||||||
body: (colon_block
|
|
||||||
(expression_statement (variable_name (name)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(text_interpolation)
|
|
||||||
)
|
|
||||||
|
|
||||||
==============================
|
|
||||||
While statements
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
while ($a < 10) {
|
|
||||||
echo $a;
|
|
||||||
$a++;
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(while_statement
|
|
||||||
condition: (parenthesized_expression (binary_expression
|
|
||||||
left: (variable_name (name))
|
|
||||||
right: (integer)))
|
|
||||||
body: (compound_statement
|
|
||||||
(echo_statement (variable_name (name)))
|
|
||||||
(expression_statement (update_expression (variable_name (name)))))))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
Alternative while statements
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
while ($a<5) echo $a++;
|
|
||||||
while ($a<9):
|
|
||||||
echo ++$a;
|
|
||||||
echo $b;
|
|
||||||
endwhile;
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(while_statement
|
|
||||||
condition: (parenthesized_expression (binary_expression
|
|
||||||
left: (variable_name (name))
|
|
||||||
right: (integer)))
|
|
||||||
body: (echo_statement (update_expression (variable_name (name)))))
|
|
||||||
(while_statement
|
|
||||||
condition: (parenthesized_expression (binary_expression
|
|
||||||
left: (variable_name (name))
|
|
||||||
right: (integer)))
|
|
||||||
body: (colon_block
|
|
||||||
(echo_statement (update_expression (variable_name (name))))
|
|
||||||
(echo_statement (variable_name (name))))))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
For statements
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
for($a=0;$a<5;$a++) echo $a;
|
|
||||||
for($a=0;$a<5;$a++):
|
|
||||||
echo $a;
|
|
||||||
endfor;
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(for_statement
|
|
||||||
(assignment_expression (variable_name (name)) (integer))
|
|
||||||
(binary_expression (variable_name (name)) (integer))
|
|
||||||
(update_expression (variable_name (name)))
|
|
||||||
(echo_statement (variable_name (name))))
|
|
||||||
(for_statement
|
|
||||||
(assignment_expression (variable_name (name)) (integer))
|
|
||||||
(binary_expression (variable_name (name)) (integer))
|
|
||||||
(update_expression (variable_name (name)))
|
|
||||||
(echo_statement (variable_name (name)))))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
Switch statements
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
switch ($a) {
|
|
||||||
case 0:
|
|
||||||
echo "bad";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
echo "good";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
echo "bad";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(switch_statement
|
|
||||||
condition: (parenthesized_expression (variable_name (name)))
|
|
||||||
body: (switch_block
|
|
||||||
(case_statement
|
|
||||||
value: (integer)
|
|
||||||
(echo_statement (encapsed_string (string_value))) (break_statement))
|
|
||||||
(case_statement
|
|
||||||
value: (integer)
|
|
||||||
(echo_statement (encapsed_string (string_value))) (break_statement))
|
|
||||||
(default_statement
|
|
||||||
(echo_statement (encapsed_string (string_value))) (break_statement))))
|
|
||||||
(text_interpolation))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
Alternative switch statements
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
switch ($a):
|
|
||||||
case 0;
|
|
||||||
echo 0;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
echo 1;
|
|
||||||
break;
|
|
||||||
default;
|
|
||||||
echo 0;
|
|
||||||
break;
|
|
||||||
endswitch;
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(switch_statement
|
|
||||||
condition: (parenthesized_expression (variable_name (name)))
|
|
||||||
body: (switch_block
|
|
||||||
(case_statement
|
|
||||||
value: (integer)
|
|
||||||
(echo_statement (integer))
|
|
||||||
(break_statement))
|
|
||||||
(case_statement
|
|
||||||
value: (integer)
|
|
||||||
(echo_statement (integer))
|
|
||||||
(break_statement))
|
|
||||||
(default_statement
|
|
||||||
(echo_statement (integer))
|
|
||||||
(break_statement)))))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
Include statement
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
include "015.inc";
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(expression_statement (include_expression (encapsed_string (string_value)))))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
Do-while statements
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
do {
|
|
||||||
echo $i;
|
|
||||||
$i--;
|
|
||||||
} while($i>0);
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(do_statement
|
|
||||||
body: (compound_statement
|
|
||||||
(echo_statement (variable_name (name)))
|
|
||||||
(expression_statement (update_expression (variable_name (name)))))
|
|
||||||
condition: (parenthesized_expression (binary_expression
|
|
||||||
left: (variable_name (name))
|
|
||||||
right: (integer)))))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
Try statements
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
try {
|
|
||||||
} catch (MyException) {
|
|
||||||
} catch (OtherException|YetAnotherException $e) {
|
|
||||||
} finally {
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
ThrowException();
|
|
||||||
} catch (MyException $exception) {
|
|
||||||
print "There was an exception: " . $exception->getException();
|
|
||||||
print "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(try_statement
|
|
||||||
body: (compound_statement)
|
|
||||||
(catch_clause
|
|
||||||
type: (type_list
|
|
||||||
(named_type (name))
|
|
||||||
)
|
|
||||||
body: (compound_statement))
|
|
||||||
(catch_clause
|
|
||||||
type: (type_list
|
|
||||||
(named_type (name))
|
|
||||||
(named_type (name))
|
|
||||||
)
|
|
||||||
name: (variable_name (name))
|
|
||||||
body: (compound_statement))
|
|
||||||
(finally_clause
|
|
||||||
body: (compound_statement)))
|
|
||||||
(try_statement
|
|
||||||
body: (compound_statement
|
|
||||||
(expression_statement (function_call_expression
|
|
||||||
function: (name)
|
|
||||||
arguments: (arguments))))
|
|
||||||
(catch_clause
|
|
||||||
type: (type_list
|
|
||||||
(named_type (name))
|
|
||||||
)
|
|
||||||
name: (variable_name (name))
|
|
||||||
body: (compound_statement
|
|
||||||
(expression_statement (print_intrinsic (binary_expression
|
|
||||||
left: (encapsed_string (string_value))
|
|
||||||
right: (member_call_expression
|
|
||||||
object: (variable_name (name))
|
|
||||||
name: (name)
|
|
||||||
arguments: (arguments)))))
|
|
||||||
(expression_statement (print_intrinsic (encapsed_string (escape_sequence))))))))
|
|
||||||
|
|
||||||
==============================
|
|
||||||
Foreach statements
|
|
||||||
==============================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
foreach ($a as $b[0]) {
|
|
||||||
echo $b[0]."\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($arr as $key => $value);
|
|
||||||
|
|
||||||
foreach($a as $b):
|
|
||||||
echo $a;
|
|
||||||
echo $b;
|
|
||||||
endforeach;
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(foreach_statement
|
|
||||||
(variable_name (name))
|
|
||||||
(subscript_expression (variable_name (name)) (integer))
|
|
||||||
body: (compound_statement
|
|
||||||
(echo_statement (binary_expression
|
|
||||||
left: (subscript_expression (variable_name (name)) (integer))
|
|
||||||
right: (encapsed_string (escape_sequence))))))
|
|
||||||
(foreach_statement
|
|
||||||
(variable_name (name))
|
|
||||||
(pair (variable_name (name)) (variable_name (name))))
|
|
||||||
(foreach_statement
|
|
||||||
(variable_name (name))
|
|
||||||
(variable_name (name))
|
|
||||||
body: (colon_block
|
|
||||||
(echo_statement (variable_name (name)))
|
|
||||||
(echo_statement (variable_name (name))))))
|
|
||||||
|
|
||||||
=================================
|
|
||||||
Case insensitive keywords
|
|
||||||
=================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
FOREACH ($a AS $b) {
|
|
||||||
DO {
|
|
||||||
if ($c) {
|
|
||||||
d();
|
|
||||||
} else {
|
|
||||||
e();
|
|
||||||
}
|
|
||||||
} while ($f);
|
|
||||||
}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(foreach_statement
|
|
||||||
(variable_name (name))
|
|
||||||
(variable_name (name))
|
|
||||||
(compound_statement
|
|
||||||
(do_statement
|
|
||||||
(compound_statement
|
|
||||||
(if_statement
|
|
||||||
(parenthesized_expression (variable_name (name)))
|
|
||||||
(compound_statement
|
|
||||||
(expression_statement (function_call_expression (name) (arguments))))
|
|
||||||
(else_clause
|
|
||||||
(compound_statement
|
|
||||||
(expression_statement (function_call_expression (name) (arguments)))))))
|
|
||||||
(parenthesized_expression (variable_name (name)))))))
|
|
||||||
|
|
||||||
|
|
||||||
=========================================
|
|
||||||
Accessing Constants
|
|
||||||
=========================================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
echo ANOTHER_CONST;
|
|
||||||
echo ANIMALS[1];
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(echo_statement
|
|
||||||
(name)
|
|
||||||
)
|
|
||||||
(echo_statement
|
|
||||||
(subscript_expression
|
|
||||||
(name)
|
|
||||||
(integer)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,171 +0,0 @@
|
|||||||
=========================
|
|
||||||
Type names
|
|
||||||
=========================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
function a(): A {}
|
|
||||||
function b(): A\B {}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(function_definition
|
|
||||||
(name) (formal_parameters)
|
|
||||||
(union_type (named_type (name)))
|
|
||||||
(compound_statement))
|
|
||||||
(function_definition
|
|
||||||
(name) (formal_parameters)
|
|
||||||
(union_type
|
|
||||||
(named_type (qualified_name (namespace_name_as_prefix (namespace_name (name))) (name)))
|
|
||||||
)
|
|
||||||
(compound_statement)))
|
|
||||||
|
|
||||||
=========================
|
|
||||||
Primitive types
|
|
||||||
=========================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
function a(): int {}
|
|
||||||
function b(): callable {}
|
|
||||||
function c(): iterable {}
|
|
||||||
function d(): never {}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(function_definition
|
|
||||||
(name) (formal_parameters)
|
|
||||||
(union_type (primitive_type))
|
|
||||||
(compound_statement))
|
|
||||||
(function_definition
|
|
||||||
(name) (formal_parameters)
|
|
||||||
(union_type (primitive_type))
|
|
||||||
(compound_statement))
|
|
||||||
(function_definition
|
|
||||||
(name) (formal_parameters)
|
|
||||||
(union_type (primitive_type))
|
|
||||||
(compound_statement))
|
|
||||||
(function_definition
|
|
||||||
(name) (formal_parameters)
|
|
||||||
(bottom_type)
|
|
||||||
(compound_statement)))
|
|
||||||
|
|
||||||
=======================
|
|
||||||
Optional types
|
|
||||||
=======================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
function a(): ?array {}
|
|
||||||
function b(): ?Something {}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(function_definition
|
|
||||||
(name) (formal_parameters)
|
|
||||||
(union_type
|
|
||||||
(optional_type (primitive_type))
|
|
||||||
)
|
|
||||||
(compound_statement))
|
|
||||||
(function_definition
|
|
||||||
(name) (formal_parameters)
|
|
||||||
(union_type
|
|
||||||
(optional_type (named_type (name)))
|
|
||||||
)
|
|
||||||
(compound_statement)))
|
|
||||||
|
|
||||||
|
|
||||||
==========================
|
|
||||||
Union types
|
|
||||||
==========================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
function a(int|string|null $var) : ?int|MyClass {}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(function_definition
|
|
||||||
name: (name)
|
|
||||||
parameters: (formal_parameters
|
|
||||||
(simple_parameter
|
|
||||||
type: (union_type
|
|
||||||
(primitive_type)
|
|
||||||
(primitive_type)
|
|
||||||
(primitive_type)
|
|
||||||
)
|
|
||||||
name: (variable_name (name))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return_type: (union_type
|
|
||||||
(optional_type
|
|
||||||
(primitive_type)
|
|
||||||
)
|
|
||||||
(named_type (name))
|
|
||||||
)
|
|
||||||
body: (compound_statement)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
==========================
|
|
||||||
Mixed type
|
|
||||||
==========================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
function a(mixed|string $var) : mixed {
|
|
||||||
|
|
||||||
}
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(function_definition
|
|
||||||
(name)
|
|
||||||
(formal_parameters
|
|
||||||
(simple_parameter
|
|
||||||
(union_type
|
|
||||||
(primitive_type)
|
|
||||||
(primitive_type)
|
|
||||||
)
|
|
||||||
(variable_name (name))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(union_type (primitive_type))
|
|
||||||
(compound_statement)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
==========================
|
|
||||||
Static type
|
|
||||||
==========================
|
|
||||||
|
|
||||||
<?php
|
|
||||||
|
|
||||||
function a(string $var) : static {
|
|
||||||
|
|
||||||
}
|
|
||||||
---
|
|
||||||
|
|
||||||
(program
|
|
||||||
(php_tag)
|
|
||||||
(function_definition
|
|
||||||
(name)
|
|
||||||
(formal_parameters
|
|
||||||
(simple_parameter
|
|
||||||
(union_type
|
|
||||||
(primitive_type)
|
|
||||||
)
|
|
||||||
(variable_name (name))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(union_type (primitive_type))
|
|
||||||
(compound_statement)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
<?php
|
|
||||||
// <- tag
|
|
||||||
|
|
||||||
if ($a) {}
|
|
||||||
// <- keyword
|
|
||||||
|
|
||||||
while ($b) {}
|
|
||||||
// <- keyword
|
|
||||||
|
|
||||||
WHILE ($b) {}
|
|
||||||
// <- keyword
|
|
||||||
|
|
||||||
do { } while ($c);
|
|
||||||
// <- keyword
|
|
||||||
// ^ keyword
|
|
||||||
|
|
||||||
try {} catch (Exception $e) {}
|
|
||||||
// <- keyword
|
|
||||||
// ^ keyword
|
|
||||||
|
|
||||||
function a() {}
|
|
||||||
// <- keyword
|
|
||||||
|
|
||||||
class A {}
|
|
||||||
// <- keyword
|
|
||||||
|
|
||||||
throw new Exception("oh");
|
|
||||||
// <- keyword
|
|
||||||
// ^ keyword
|
|
||||||
|
|
||||||
function b(
|
|
||||||
int $a,
|
|
||||||
// <- type.builtin
|
|
||||||
|
|
||||||
string $b,
|
|
||||||
// <- type.builtin
|
|
||||||
|
|
||||||
Person $e
|
|
||||||
// ^ type
|
|
||||||
): Dog {}
|
|
||||||
// ^ type
|
|
||||||
|
|
||||||
interface T {}
|
|
||||||
// ^ keyword
|
|
||||||
|
|
||||||
trait T {}
|
|
||||||
// ^ keyword
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
echo <<<OMG
|
|
||||||
something
|
|
||||||
OMG
|
|
||||||
// <- string
|
|
||||||
|
|
||||||
echo true, TRUE, false, FALSE
|
|
||||||
// ^ constant.builtin
|
|
||||||
// ^ constant.builtin
|
|
||||||
// ^ constant.builtin
|
|
||||||
// ^ constant.builtin
|
|
||||||
|
|
||||||
echo PI_314
|
|
||||||
// ^ constant
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
function a(array $b, Something $c) {
|
|
||||||
// ^ type.builtin
|
|
||||||
// ^ type
|
|
||||||
echo (int) $foo;
|
|
||||||
// ^ type.builtin
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue