mirror of https://github.com/Wilfred/difftastic/
commit
72c606331a
@ -0,0 +1,38 @@
|
|||||||
|
use strict 'refs';
|
||||||
|
use warnings;
|
||||||
|
use if $] < 5.008, "utf8";
|
||||||
|
use if WANT_WARNINGS, warnings => qw(all);
|
||||||
|
|
||||||
|
use constant PI => 4 * atan2(1, 1);
|
||||||
|
use constant DEBUG , 0; # comma (,) is also used instead of '=>'
|
||||||
|
|
||||||
|
print "Pi equals ", PI, "...\n";
|
||||||
|
|
||||||
|
use constant {
|
||||||
|
SEC => 0,
|
||||||
|
MIN => 1,
|
||||||
|
HOUR => 2,
|
||||||
|
MDAY => 3,
|
||||||
|
MON => 4,
|
||||||
|
YEAR => 5,
|
||||||
|
WDAY => 6,
|
||||||
|
YDAY => 7,
|
||||||
|
ISDST => 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
my $setting = {
|
||||||
|
open => 1,
|
||||||
|
close => 2,
|
||||||
|
run => 3,
|
||||||
|
awesome => 'yes',
|
||||||
|
};
|
||||||
|
my %final;
|
||||||
|
foreach my $key (woof()) {
|
||||||
|
$final{IRONMAN}{$key} = $setting->{$key};
|
||||||
|
|
||||||
|
print Dumper \%final;
|
||||||
|
}
|
||||||
|
|
||||||
|
use constant WEEKDAYS => qw(
|
||||||
|
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
|
||||||
|
);
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
use strict 'refs';
|
||||||
|
use warnings;
|
||||||
|
use if $] < 5.008, "utf8";
|
||||||
|
use if WANT_WARNINGS, warnings => qw(all);
|
||||||
|
|
||||||
|
use constant PI => 4 * atan2(1, 1);
|
||||||
|
use constant DEBUG , 0; # comma (,) is also used instead of '=>'
|
||||||
|
|
||||||
|
print "Pi equals ", PI, "...\n";
|
||||||
|
|
||||||
|
use constant {
|
||||||
|
SEC => 0,
|
||||||
|
MIN => 1,
|
||||||
|
HOUR => 2,
|
||||||
|
MDAY => 3,
|
||||||
|
MON => 4,
|
||||||
|
YEAR => 5,
|
||||||
|
WDAY => 6,
|
||||||
|
YDAY => 7,
|
||||||
|
ISDST => 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
use constant WEEKDAYS => qw(
|
||||||
|
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
|
||||||
|
);
|
||||||
@ -0,0 +1 @@
|
|||||||
|
tree-sitter-perl/src
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
# node stuffs
|
||||||
|
node_modules/
|
||||||
|
.npmrc
|
||||||
|
|
||||||
|
# some build stuff
|
||||||
|
9.3.5/
|
||||||
|
bin/
|
||||||
|
build/
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"${workspaceFolder}/src"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/bin/gcc",
|
||||||
|
"cStandard": "gnu17",
|
||||||
|
"cppStandard": "gnu++14",
|
||||||
|
"intelliSenseMode": "linux-gcc-x64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"bareword",
|
||||||
|
"prec"
|
||||||
|
],
|
||||||
|
"files.associations": {
|
||||||
|
"vector": "cpp"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
[package]
|
||||||
|
name = "tree-sitter-perl"
|
||||||
|
description = "perl grammar for the tree-sitter parsing library"
|
||||||
|
version = "0.0.1"
|
||||||
|
keywords = ["incremental", "parsing", "perl"]
|
||||||
|
categories = ["parsing", "text-editors"]
|
||||||
|
repository = "https://github.com/tree-sitter/tree-sitter-javascript"
|
||||||
|
edition = "2018"
|
||||||
|
license = "MIT"
|
||||||
|
|
||||||
|
build = "bindings/rust/build.rs"
|
||||||
|
include = [
|
||||||
|
"bindings/rust/*",
|
||||||
|
"grammar.js",
|
||||||
|
"queries/*",
|
||||||
|
"src/*",
|
||||||
|
]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "bindings/rust/lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tree-sitter = "0.17"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
cc = "1.0"
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Ganesan
|
||||||
|
|
||||||
|
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.
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
# tree-sitter-perl
|
||||||
|
a perl parser for javascript
|
||||||
|
|
||||||
|
## To generate the parser output
|
||||||
|
`npm run generate`
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
`npm run test`
|
||||||
|
|
||||||
|
## Run examples
|
||||||
|
|
||||||
|
`npm run example`
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"target_name": "tree_sitter_perl_binding",
|
||||||
|
"include_dirs": [
|
||||||
|
"<!(node -e \"require('nan')\")",
|
||||||
|
"src"
|
||||||
|
],
|
||||||
|
"sources": [
|
||||||
|
"src/parser.c",
|
||||||
|
"src/scanner.cc",
|
||||||
|
"bindings/node/binding.cc"
|
||||||
|
],
|
||||||
|
"cflags_c": [
|
||||||
|
"-std=c99",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
#include "tree_sitter/parser.h"
|
||||||
|
#include <node.h>
|
||||||
|
#include "nan.h"
|
||||||
|
|
||||||
|
using namespace v8;
|
||||||
|
|
||||||
|
extern "C" TSLanguage * tree_sitter_perl();
|
||||||
|
|
||||||
|
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_perl());
|
||||||
|
|
||||||
|
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("perl").ToLocalChecked());
|
||||||
|
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
NODE_MODULE(tree_sitter_perl_binding, Init)
|
||||||
|
|
||||||
|
} // namespace
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
try {
|
||||||
|
module.exports = require("../../build/Release/tree_sitter_perl_binding");
|
||||||
|
} catch (error1) {
|
||||||
|
if (error1.code !== 'MODULE_NOT_FOUND') {
|
||||||
|
throw error1;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
module.exports = require("../../build/Debug/tree_sitter_perl_binding");
|
||||||
|
} catch (error2) {
|
||||||
|
if (error2.code !== 'MODULE_NOT_FOUND') {
|
||||||
|
throw error2;
|
||||||
|
}
|
||||||
|
throw error1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
module.exports.nodeTypeInfo = require("../../src/node-types.json");
|
||||||
|
} catch (_) {}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
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);
|
||||||
|
|
||||||
|
// If your language uses an external scanner written in C,
|
||||||
|
// then include this block of code:
|
||||||
|
|
||||||
|
/*
|
||||||
|
let scanner_path = src_dir.join("scanner.c");
|
||||||
|
c_config.file(&scanner_path);
|
||||||
|
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
|
||||||
|
*/
|
||||||
|
|
||||||
|
c_config.compile("parser");
|
||||||
|
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
cpp_config.compile("scanner");
|
||||||
|
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
|
||||||
|
*/
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
//! This crate provides perl 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_perl::language()).expect("Error loading perl 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_perl() -> 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_perl() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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 HIGHLIGHTS_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 perl language");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
package BaseModule::YeaThis;
|
||||||
|
|
||||||
|
use parent 'PerlModule';
|
||||||
|
|
||||||
|
$foo::bar = 1;
|
||||||
|
|
||||||
|
BaseModule::YeaThis->new->hello();
|
||||||
|
|
||||||
|
my $simple = SimpleModule->new();
|
||||||
|
|
||||||
|
my $parent_call = $self->SUPER::Something($string);
|
||||||
|
|
||||||
|
|
||||||
|
my $event = {
|
||||||
|
user_id => Data::UUID->new->Something($dbh, {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
my $output = {
|
||||||
|
some_property => BaseModule::AtSomeWhere::GetSomething(121, {
|
||||||
|
KEY => $var->{there},
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
my $object_return = BaseModule::AtSomeWhere::GetSomething(121, {
|
||||||
|
KEY => $var->{there}->{here},
|
||||||
|
})->SomeOtherSub('hahaha');
|
||||||
|
|
||||||
|
=pod
|
||||||
|
=head1 Heading Text
|
||||||
|
=head2 Heading Text
|
||||||
|
=head3 Heading Text
|
||||||
|
=head4 Heading Text
|
||||||
|
=over indentlevel
|
||||||
|
=item stuff
|
||||||
|
=back
|
||||||
|
=begin format
|
||||||
|
=end format
|
||||||
|
=for format text...
|
||||||
|
=encoding type
|
||||||
|
=end
|
||||||
|
|
||||||
|
print "Well hello beautiful";
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
package PerlModule;
|
||||||
|
|
||||||
|
use 5.006;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Carp ();
|
||||||
|
|
||||||
|
use vars qw{$VERSION};
|
||||||
|
BEGIN {
|
||||||
|
$VERSION = '1.04';
|
||||||
|
|
||||||
|
# Optional stacktrace support
|
||||||
|
eval "require Devel::StackTrace";
|
||||||
|
}
|
||||||
|
|
||||||
|
# my $another = BaseModule::YeaThis->new()->hello();
|
||||||
|
|
||||||
|
# eval {
|
||||||
|
# package hello;
|
||||||
|
# };
|
||||||
|
|
||||||
|
new();
|
||||||
|
getTrace();
|
||||||
|
toString();
|
||||||
|
|
||||||
|
sub new {
|
||||||
|
my $class = shift;
|
||||||
|
bless {}, $class;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $output = BaseModule::YeaThis::hello('first', {
|
||||||
|
hello => 'beautiful'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
sub getTrace {
|
||||||
|
$_[0]->{Trace};
|
||||||
|
}
|
||||||
|
|
||||||
|
# sub fillTrace {
|
||||||
|
# my $self = shift;
|
||||||
|
# $self->{Trace} = Devel::StackTrace->new(
|
||||||
|
# ignore_class => [__PACKAGE__, @_],
|
||||||
|
# ) if $Devel::StackTrace::VERSION;
|
||||||
|
# }
|
||||||
|
|
||||||
|
sub getCarp {
|
||||||
|
$_[0]->{Carp};
|
||||||
|
}
|
||||||
|
|
||||||
|
# sub fillCarp {
|
||||||
|
# my $self = shift;
|
||||||
|
# my $msg = shift;
|
||||||
|
# $Carp::Internal{ __PACKAGE__ . "" }++;
|
||||||
|
# local $Carp::CarpLevel = $Carp::CarpLevel + 1;
|
||||||
|
# $self->{Carp} = Carp::longmess($msg);
|
||||||
|
# $Carp::Internal{ __PACKAGE__ . "" }--;
|
||||||
|
# }
|
||||||
|
|
||||||
|
sub getMessage {
|
||||||
|
$_[0]->{Message};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub setMessage {
|
||||||
|
$_[0]->{Message} = $_[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
sub fillTest {
|
||||||
|
my $self = shift;
|
||||||
|
my $builder = shift;
|
||||||
|
my $prev_test = $builder->current_test;
|
||||||
|
$self->{Test} = $prev_test;
|
||||||
|
my @tests = $builder->details;
|
||||||
|
my $prev_test_name = $prev_test ? $tests[$prev_test - 1]->{name} : "";
|
||||||
|
$self->{TestName} = $prev_test_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getTest {
|
||||||
|
$_[0]->{Test};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getTestName {
|
||||||
|
$_[0]->{TestName};
|
||||||
|
}
|
||||||
|
|
||||||
|
# sub toString {
|
||||||
|
# my $self = shift;
|
||||||
|
# return <<EOM;
|
||||||
|
# Previous test $self->{Test} '$self->{TestName}'
|
||||||
|
# $self->{Carp}
|
||||||
|
# EOM
|
||||||
|
# }
|
||||||
|
|
||||||
|
|
||||||
|
1;
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
# sub hello {
|
||||||
|
# if (1) {
|
||||||
|
# return true;
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
# hello();
|
||||||
|
|
||||||
|
if (1) {
|
||||||
|
print "if condition\n";
|
||||||
|
}
|
||||||
|
# comments comments everywhere
|
||||||
|
# comments comments everywhere
|
||||||
|
elsif(1) {
|
||||||
|
print "meow\n";
|
||||||
|
}
|
||||||
|
# comments comments everywhere
|
||||||
|
# comments comments everywhere
|
||||||
|
elsif(1) {
|
||||||
|
print "another one\n";
|
||||||
|
}
|
||||||
|
# comments comments everywhere
|
||||||
|
# comments comments everywhere
|
||||||
|
else {
|
||||||
|
print "else print this\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
unless(0) {
|
||||||
|
print "unless\n";
|
||||||
|
}
|
||||||
|
elsif(1) {
|
||||||
|
print "meow\n";
|
||||||
|
}
|
||||||
|
elsif(1) {
|
||||||
|
print "another one\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "else print this\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# my $num = rand();
|
||||||
|
|
||||||
|
# given ($num) {
|
||||||
|
# when (1) {
|
||||||
|
# say "is larger than 0.7";
|
||||||
|
# }
|
||||||
|
# when ($_ > 0.4) {
|
||||||
|
# say "$_ is larger than 0.4";
|
||||||
|
# }
|
||||||
|
# default {
|
||||||
|
# say "$_ is something else";
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
# my $i = 0;
|
||||||
|
# MEOW: while ($i < 10) {
|
||||||
|
# print "hello $i";
|
||||||
|
|
||||||
|
# next MEOW;
|
||||||
|
|
||||||
|
# $i++;
|
||||||
|
# }
|
||||||
|
|
||||||
|
# standalone blocks
|
||||||
|
{
|
||||||
|
print "hello";
|
||||||
|
} continue {
|
||||||
|
print "con\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
my @array = ("dsf");
|
||||||
|
|
||||||
|
my $tern_out = (1 == 1) ? ("terry") : ((2 * 28) + 1);
|
||||||
|
|
||||||
|
print $tern_out;
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
use feature 'switch';
|
||||||
|
use v5.14;
|
||||||
|
use Try::Tiny;
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
my $a = 1;
|
||||||
|
print "tying..\n";
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
print "catch block";
|
||||||
|
};
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Data::Dumper;
|
||||||
|
use feature 'signatures';
|
||||||
|
|
||||||
|
sub simple {
|
||||||
|
# my @args = @_;
|
||||||
|
print "this is simple\n";
|
||||||
|
my $variable = 1;
|
||||||
|
|
||||||
|
print $variable;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print "hello world!\n";
|
||||||
|
|
||||||
|
my $hello = "hello";
|
||||||
|
|
||||||
|
print $hello;
|
||||||
|
|
||||||
|
simple;
|
||||||
|
simple();
|
||||||
|
simple('hola');
|
||||||
|
|
||||||
|
sub foo : Expose ($left, $right) {
|
||||||
|
return $left + $right;
|
||||||
|
}
|
||||||
|
|
||||||
|
foo();
|
||||||
|
print "\n";
|
||||||
|
my @chars = map chr, qw(1 2 3);
|
||||||
|
print "chars..." . Dumper \@chars;
|
||||||
|
|
||||||
|
map chr, qw(1 2 30);
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
# hash needs its own sweet example file
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
|
my $simple = SimpleModule->new();
|
||||||
|
|
||||||
|
|
||||||
|
my $event = {
|
||||||
|
user_id => Data::UUID->new->Something($simple, {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
my $output = {
|
||||||
|
some_property => BaseModule::AtSomeWhere::GetSomething(121, {
|
||||||
|
KEY => $var->{there},
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
my $ter = {
|
||||||
|
first => 'something here',
|
||||||
|
hello() ? (second => 1) : (third => 'ternary false'),
|
||||||
|
};
|
||||||
|
|
||||||
|
print Dumper $ter->{first};
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
use strict 'refs';
|
||||||
|
use warnings;
|
||||||
|
use if $] < 5.008, "utf8";
|
||||||
|
use if WANT_WARNINGS, warnings => qw(all);
|
||||||
|
|
||||||
|
use constant PI => 4 * atan2(1, 1);
|
||||||
|
use constant DEBUG , 0; # comma (,) is also used instead of '=>'
|
||||||
|
|
||||||
|
print "Pi equals ", PI, "...\n";
|
||||||
|
|
||||||
|
use constant {
|
||||||
|
SEC => 0,
|
||||||
|
MIN => 1,
|
||||||
|
HOUR => 2,
|
||||||
|
MDAY => 3,
|
||||||
|
MON => 4,
|
||||||
|
YEAR => 5,
|
||||||
|
WDAY => 6,
|
||||||
|
YDAY => 7,
|
||||||
|
ISDST => 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
use constant WEEKDAYS => qw(
|
||||||
|
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
|
||||||
|
);
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
|
foreach my $value (qw( cat dog bird flight superman )) {
|
||||||
|
print $value . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $setting = {
|
||||||
|
open => 1,
|
||||||
|
close => 2,
|
||||||
|
run => 3,
|
||||||
|
awesome => 'yes',
|
||||||
|
};
|
||||||
|
my %final;
|
||||||
|
foreach my $key (woof()) {
|
||||||
|
$final{IRONMAN}{$key} = $setting->{$key};
|
||||||
|
|
||||||
|
print Dumper \%final;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub woof {}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
# ellipsis
|
||||||
|
{ ... }
|
||||||
|
sub foo { ... }
|
||||||
|
...;
|
||||||
|
sub somemeth {
|
||||||
|
my $self = shift;
|
||||||
|
...;
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
use Data::Dumper;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
my $ls_args = '-a';
|
||||||
|
my $ls_command = qx /ls $ls_args/;
|
||||||
|
|
||||||
|
|
||||||
|
# print Dumper $ls_command;
|
||||||
|
|
||||||
|
my @array = qw / s6df 32 DF /;
|
||||||
|
|
||||||
|
# print Dumper \@array;
|
||||||
|
|
||||||
|
my $string = 'a simple string';
|
||||||
|
$string = 'string with # in it';
|
||||||
|
$string = 'string with escape \' sequence';
|
||||||
|
$string =~ m/Simple/is;
|
||||||
|
my $baa = 'bbb';
|
||||||
|
$_ = "AAA bbb AAA";
|
||||||
|
print "Found bbb\n" if m/$baa/;
|
||||||
|
|
||||||
|
# Printing the String
|
||||||
|
print "Before: $`\n";
|
||||||
|
print "Matched: $&\n";
|
||||||
|
print "After: $'\n";
|
||||||
|
|
||||||
|
|
||||||
|
my $rex = qr/my.STRING/is;
|
||||||
|
|
||||||
|
print "rex..\n" . $rex;
|
||||||
|
|
||||||
|
my $subs = 'my here string';
|
||||||
|
$subs =~ s/my.STRING/foo/is;
|
||||||
|
|
||||||
|
print "\n substitute is.. \n" . $subs;
|
||||||
|
|
||||||
|
my $trans = "hello";
|
||||||
|
$trans =~ tr/h-l/H-L/c;
|
||||||
|
|
||||||
|
print "\n tr is.. \n" . $trans;
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
|
sub hello {
|
||||||
|
return 'hello';
|
||||||
|
}
|
||||||
|
|
||||||
|
# single declaration and initialization
|
||||||
|
my $a;
|
||||||
|
|
||||||
|
my @array;
|
||||||
|
|
||||||
|
my $number = 3010; # number
|
||||||
|
|
||||||
|
my $negative_number = -18;
|
||||||
|
|
||||||
|
my $floating_number = 5.5;
|
||||||
|
|
||||||
|
my $floating_negative_number = -7.455;
|
||||||
|
|
||||||
|
my $string = 'hello'; # single quoted string
|
||||||
|
my $empty_string = '';
|
||||||
|
|
||||||
|
my $double_quoted_string = "meow";
|
||||||
|
|
||||||
|
my $scientific_notation = 16.12E14;
|
||||||
|
|
||||||
|
my $hexa_decimal = 0xffff;
|
||||||
|
|
||||||
|
my $octal = 0577;
|
||||||
|
|
||||||
|
|
||||||
|
my @array2 = ('m\'eow', 'woof', 'burp',);
|
||||||
|
|
||||||
|
my @number_array = ( 1, 2, 3, 8 );
|
||||||
|
|
||||||
|
my @mixed_array = ($octal, 4, 'dog', 4 * 7);
|
||||||
|
|
||||||
|
print "mixed". Dumper(\@mixed_array);
|
||||||
|
|
||||||
|
my @empty_array = ();
|
||||||
|
|
||||||
|
|
||||||
|
# multi declarations and initialization
|
||||||
|
|
||||||
|
# my ($b, $c) = ();
|
||||||
|
|
||||||
|
my $array_ref = ['string', 123, "double string"];
|
||||||
|
|
||||||
|
my $hash = {
|
||||||
|
'cat' => 'meow',
|
||||||
|
"cow" => 'moo',
|
||||||
|
dog => 'woof',
|
||||||
|
};
|
||||||
|
|
||||||
|
my %hash = (
|
||||||
|
believer => 'i am',
|
||||||
|
at => 'important things',
|
||||||
|
first_things => 1,
|
||||||
|
seconds_things => 2,
|
||||||
|
);
|
||||||
|
|
||||||
|
my $hash2 = {
|
||||||
|
name => 'dog',
|
||||||
|
sound => 'woof',
|
||||||
|
};
|
||||||
|
|
||||||
|
$hash->{ wag } = 'tail';
|
||||||
|
$hash->{inner}->{prop1} = 'secret';
|
||||||
|
$hash->{inner}->{prop2}->[0.3] = 'secret2';
|
||||||
|
|
||||||
|
# type glob
|
||||||
|
local *something = \$hash;
|
||||||
|
*somethingelse = *something;
|
||||||
|
print Dumper *somethingelse;
|
||||||
|
|
||||||
|
|
||||||
|
print Dumper $hash;
|
||||||
|
|
||||||
|
|
||||||
|
my @array5 = (1, 3, 6);
|
||||||
|
|
||||||
|
$array5[5] = 23;
|
||||||
|
|
||||||
|
my $prev_test = 10;
|
||||||
|
$array5[$prev_test - 1]->{name} = 1;
|
||||||
|
|
||||||
|
|
||||||
|
print Dumper(\@array5);
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
use strict 'refs';
|
||||||
|
use warnings;
|
||||||
|
use Data::Dumper;
|
||||||
|
use Try::Tiny;
|
||||||
|
|
||||||
|
my $var = 'some string';
|
||||||
|
|
||||||
|
# my $hashref = {
|
||||||
|
# someThing => 'hey hey',
|
||||||
|
# };
|
||||||
|
|
||||||
|
# my %hash = (
|
||||||
|
# makes => 'sense',
|
||||||
|
# );
|
||||||
|
|
||||||
|
|
||||||
|
print 'one\'s true \\love';
|
||||||
|
|
||||||
|
print "\na simple string $var and $hash->{someThing}, haha\n";
|
||||||
|
|
||||||
|
print qq /jkj/;
|
||||||
|
|
||||||
|
print qq {\n {df {fsdf {dsf }}} ( im on vacation};
|
||||||
|
|
||||||
|
print qq {sdf $hashref->{someThing} im on vacation};
|
||||||
|
|
||||||
|
print qq{$var is better than no string\n};
|
||||||
|
|
||||||
|
print qq{\nDoes this make $hash{makes}, really?};
|
||||||
|
|
||||||
|
print qq {hello{ dsf {ds {\}}}}};
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"name": "@ganezdragon/tree-sitter-perl",
|
||||||
|
"version": "0.2.1",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"nan": {
|
||||||
|
"version": "2.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
|
||||||
|
"integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
|
||||||
|
},
|
||||||
|
"tree-sitter-cli": {
|
||||||
|
"version": "0.19.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.19.4.tgz",
|
||||||
|
"integrity": "sha512-p2kxjuoQeauXBu5eE+j7c5BMCRXmc17EiAswnnWn3ieUlHXBkA0Z7vRnaCSElDR34MhZnSgqgzuuzQk0cDqCjw==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "@ganezdragon/tree-sitter-perl",
|
||||||
|
"version": "0.3.0",
|
||||||
|
"description": "a tree-sitter for perl language.",
|
||||||
|
"main": "bindings/node",
|
||||||
|
"scripts": {
|
||||||
|
"generate": "tree-sitter generate",
|
||||||
|
"test": "tree-sitter test",
|
||||||
|
"example": "tree-sitter parse examples/*"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"registry": "https://npm.pkg.github.com/"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"perl",
|
||||||
|
"parser",
|
||||||
|
"nodejs"
|
||||||
|
],
|
||||||
|
"repository": "git://github.com/ganezdragon/tree-sitter-perl.git",
|
||||||
|
"author": "ganezdragon",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"nan": "^2.14.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"tree-sitter-cli": "^0.19.4"
|
||||||
|
},
|
||||||
|
"tree-sitter": [
|
||||||
|
{
|
||||||
|
"scope": "source.perl",
|
||||||
|
"file-types": [
|
||||||
|
"pl"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
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
@ -0,0 +1,590 @@
|
|||||||
|
#include <tree_sitter/parser.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
using std::memcpy;
|
||||||
|
|
||||||
|
enum TokenType {
|
||||||
|
START_DELIMITER,
|
||||||
|
END_DELIMITER,
|
||||||
|
STRING_CONTENT,
|
||||||
|
STRING_SINGLE_QUOTED_CONTENT,
|
||||||
|
STRING_QQ_QUOTED_CONTENT,
|
||||||
|
STRING_DOUBLE_QUOTED_CONTENT,
|
||||||
|
START_DELIMITER_QW,
|
||||||
|
ELEMENT_IN_QW,
|
||||||
|
END_DELIMITER_QW,
|
||||||
|
START_DELIMITER_REGEX,
|
||||||
|
REGEX_PATTERN,
|
||||||
|
END_DELIMITER_REGEX,
|
||||||
|
START_DELIMITER_SEARCH_REPLACE,
|
||||||
|
SEARCH_REPLACE_CONTENT,
|
||||||
|
SEPARATOR_DELIMITER_SEARCH_REPLACE,
|
||||||
|
END_DELIMITER_SEARCH_REPLACE,
|
||||||
|
START_DELIMITER_TRANSLITERATION,
|
||||||
|
TRANSLITERATION_CONTENT,
|
||||||
|
SEPARATOR_DELIMITER_TRANSLITERATION,
|
||||||
|
END_DELIMITER_TRANSLITERATION,
|
||||||
|
POD_CONTENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Delimiter {
|
||||||
|
|
||||||
|
int32_t get_end_delimiter() {
|
||||||
|
return end_delimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t end_delimiter;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Scanner {
|
||||||
|
Scanner() {
|
||||||
|
// assert(sizeof(Delimiter) == sizeof(char));
|
||||||
|
deserialize(NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned serialize(char *buffer) {
|
||||||
|
size_t no_of_bytes = 0;
|
||||||
|
|
||||||
|
// size_t delimiter_count = delimiter_stack.size();
|
||||||
|
// if (delimiter_count > UINT8_MAX) delimiter_count = UINT8_MAX;
|
||||||
|
// buffer[no_of_bytes++] = delimiter_count;
|
||||||
|
|
||||||
|
// if (delimiter_count > 0) {
|
||||||
|
// memcpy(&buffer[no_of_bytes], delimiter_stack.data(), delimiter_count);
|
||||||
|
// }
|
||||||
|
// no_of_bytes += delimiter_count;
|
||||||
|
|
||||||
|
return no_of_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deserialize(const char *buffer, unsigned length) {
|
||||||
|
// delimiter_stack.clear();
|
||||||
|
|
||||||
|
// if (length > 0) {
|
||||||
|
// size_t no_of_bytes = 0;
|
||||||
|
|
||||||
|
// size_t delimiter_count = (uint8_t)buffer[no_of_bytes++];
|
||||||
|
// delimiter_stack.resize(delimiter_count);
|
||||||
|
// if (delimiter_count > 0) {
|
||||||
|
// memcpy(delimiter_stack.data(), &buffer[no_of_bytes], delimiter_count);
|
||||||
|
// }
|
||||||
|
// no_of_bytes += delimiter_count;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool scan(TSLexer *lexer, const bool *valid_symbols) {
|
||||||
|
// on ERROR, external scanner is called with all valid_symbols to be true.
|
||||||
|
// so for our usecase we need this logic.
|
||||||
|
// ref - https://github.com/tree-sitter/tree-sitter/issues/1128
|
||||||
|
if (
|
||||||
|
valid_symbols[START_DELIMITER]
|
||||||
|
&& valid_symbols[END_DELIMITER]
|
||||||
|
&& valid_symbols[STRING_CONTENT]
|
||||||
|
&& valid_symbols[STRING_SINGLE_QUOTED_CONTENT]
|
||||||
|
&& valid_symbols[STRING_QQ_QUOTED_CONTENT]
|
||||||
|
&& valid_symbols[STRING_DOUBLE_QUOTED_CONTENT]
|
||||||
|
&& valid_symbols[START_DELIMITER_QW]
|
||||||
|
&& valid_symbols[END_DELIMITER_QW]
|
||||||
|
&& valid_symbols[START_DELIMITER_REGEX]
|
||||||
|
&& valid_symbols[REGEX_PATTERN]
|
||||||
|
&& valid_symbols[END_DELIMITER_REGEX]
|
||||||
|
&& valid_symbols[START_DELIMITER_SEARCH_REPLACE]
|
||||||
|
&& valid_symbols[SEARCH_REPLACE_CONTENT]
|
||||||
|
&& valid_symbols[SEPARATOR_DELIMITER_SEARCH_REPLACE]
|
||||||
|
&& valid_symbols[END_DELIMITER_SEARCH_REPLACE]
|
||||||
|
&& valid_symbols[START_DELIMITER_TRANSLITERATION]
|
||||||
|
&& valid_symbols[TRANSLITERATION_CONTENT]
|
||||||
|
&& valid_symbols[SEPARATOR_DELIMITER_TRANSLITERATION]
|
||||||
|
&& valid_symbols[END_DELIMITER_TRANSLITERATION]
|
||||||
|
&& valid_symbols[POD_CONTENT]
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_symbols[STRING_SINGLE_QUOTED_CONTENT]) {
|
||||||
|
|
||||||
|
// end when you reach the final single quote '
|
||||||
|
if (lexer->lookahead == '\'') {
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
advance(lexer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// check for escaped single quote \'
|
||||||
|
else if (lexer->lookahead == '\\') {
|
||||||
|
lexer->result_symbol = STRING_SINGLE_QUOTED_CONTENT;
|
||||||
|
advance(lexer);
|
||||||
|
|
||||||
|
if (lexer->lookahead == '\'') {
|
||||||
|
advance(lexer);
|
||||||
|
}
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// some exit conditions
|
||||||
|
if (!lexer->lookahead) {
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer->result_symbol = STRING_SINGLE_QUOTED_CONTENT;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: handle qqqSTRINGq; - this should throw error
|
||||||
|
if (valid_symbols[START_DELIMITER]) {
|
||||||
|
return parse_start_delimiter(lexer, START_DELIMITER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_symbols[STRING_QQ_QUOTED_CONTENT]) {
|
||||||
|
return parse_delimited_and_interpolated_content(lexer, STRING_QQ_QUOTED_CONTENT, END_DELIMITER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_symbols[STRING_DOUBLE_QUOTED_CONTENT]) {
|
||||||
|
if (lexer->lookahead == '"') {
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
advance(lexer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// oh boy! the interpolation
|
||||||
|
if (lexer->lookahead == '$') {
|
||||||
|
return handle_interpolation(lexer, STRING_DOUBLE_QUOTED_CONTENT);
|
||||||
|
}
|
||||||
|
// escape sequences, only basic support as of now
|
||||||
|
if (lexer->lookahead == '\\') {
|
||||||
|
return handle_escape_sequence(lexer, STRING_DOUBLE_QUOTED_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// some exit conditions
|
||||||
|
if (!lexer->lookahead) {
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer->result_symbol = STRING_DOUBLE_QUOTED_CONTENT;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_symbols[START_DELIMITER_QW]) {
|
||||||
|
return parse_start_delimiter(lexer, START_DELIMITER_QW);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_symbols[ELEMENT_IN_QW]) {
|
||||||
|
run_over_spaces(lexer);
|
||||||
|
|
||||||
|
if (lexer->lookahead == get_end_delimiter()) {
|
||||||
|
lexer->result_symbol = END_DELIMITER_QW;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// exit condition
|
||||||
|
if (!lexer->lookahead) {
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (
|
||||||
|
lexer->lookahead != ' '
|
||||||
|
&& lexer->lookahead != '\t'
|
||||||
|
&& lexer->lookahead != '\r'
|
||||||
|
&& lexer->lookahead != '\n'
|
||||||
|
&& lexer->lookahead != get_end_delimiter()
|
||||||
|
) {
|
||||||
|
lexer->result_symbol = ELEMENT_IN_QW;
|
||||||
|
advance(lexer);
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_symbols[START_DELIMITER_REGEX]) {
|
||||||
|
return parse_start_delimiter(lexer, START_DELIMITER_REGEX);
|
||||||
|
}
|
||||||
|
if (valid_symbols[REGEX_PATTERN]) {
|
||||||
|
return parse_delimited_and_interpolated_content(lexer, REGEX_PATTERN, END_DELIMITER_REGEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_symbols[START_DELIMITER_SEARCH_REPLACE]) {
|
||||||
|
return parse_start_delimiter(lexer, START_DELIMITER_SEARCH_REPLACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_symbols[SEARCH_REPLACE_CONTENT]) {
|
||||||
|
if (lexer->lookahead == get_end_delimiter()) {
|
||||||
|
return process_separator_delimiter(lexer, SEPARATOR_DELIMITER_SEARCH_REPLACE, END_DELIMITER_SEARCH_REPLACE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// oh boy! the interpolation
|
||||||
|
if (lexer->lookahead == '$') {
|
||||||
|
return handle_interpolation(lexer, SEARCH_REPLACE_CONTENT);
|
||||||
|
}
|
||||||
|
// escape sequences, only basic support as of now
|
||||||
|
if (lexer->lookahead == '\\') {
|
||||||
|
return handle_escape_sequence(lexer, SEARCH_REPLACE_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// some exit conditions
|
||||||
|
if (!lexer->lookahead) {
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handling nested delimiters qq { hello { from { the}}};
|
||||||
|
if (lexer->lookahead == start_delimiter_char) {
|
||||||
|
lexer->result_symbol = SEARCH_REPLACE_CONTENT;
|
||||||
|
advance(lexer);
|
||||||
|
return scan_nested_delimiters(lexer, SEARCH_REPLACE_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer->result_symbol = SEARCH_REPLACE_CONTENT;
|
||||||
|
advance(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_symbols[START_DELIMITER_TRANSLITERATION]) {
|
||||||
|
return parse_start_delimiter(lexer, START_DELIMITER_TRANSLITERATION);
|
||||||
|
}
|
||||||
|
if (valid_symbols[TRANSLITERATION_CONTENT]) {
|
||||||
|
if (lexer->lookahead == get_end_delimiter()) {
|
||||||
|
return process_separator_delimiter(lexer, SEPARATOR_DELIMITER_TRANSLITERATION, END_DELIMITER_TRANSLITERATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
// exit condition
|
||||||
|
if (!lexer->lookahead) {
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// escape sequence
|
||||||
|
if (lexer->lookahead == '\\') {
|
||||||
|
lexer->result_symbol = TRANSLITERATION_CONTENT;
|
||||||
|
advance(lexer);
|
||||||
|
// self end delimiter
|
||||||
|
if (lexer->lookahead == get_end_delimiter()) {
|
||||||
|
advance(lexer);
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handling nested delimiters qq { hello { from { the}}};
|
||||||
|
if (lexer->lookahead == start_delimiter_char) {
|
||||||
|
lexer->result_symbol = TRANSLITERATION_CONTENT;
|
||||||
|
advance(lexer);
|
||||||
|
return scan_nested_delimiters(lexer, TRANSLITERATION_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer->result_symbol = TRANSLITERATION_CONTENT;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_symbols[POD_CONTENT]) {
|
||||||
|
|
||||||
|
while (lexer->lookahead) {
|
||||||
|
lexer->result_symbol = POD_CONTENT;
|
||||||
|
|
||||||
|
// if it is =cut that marks the end of pod content
|
||||||
|
if (lexer->lookahead == '=') {
|
||||||
|
lexer->advance(lexer, false);
|
||||||
|
if (lexer->lookahead == 'c') {
|
||||||
|
lexer->advance(lexer, false);
|
||||||
|
if (lexer->lookahead == 'u') {
|
||||||
|
lexer->advance(lexer, false);
|
||||||
|
if (lexer->lookahead == 't') {
|
||||||
|
lexer->advance(lexer, false);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lexer->advance(lexer, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// or if it end of the file also, mark the end of pod content
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parse_delimited_and_interpolated_content(TSLexer *lexer, TokenType token_type, TokenType ending_delimiter) {
|
||||||
|
if (lexer->lookahead == get_end_delimiter()) {
|
||||||
|
lexer->result_symbol = ending_delimiter;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// oh boy! the interpolation
|
||||||
|
if (lexer->lookahead == '$') {
|
||||||
|
return handle_interpolation(lexer, token_type);
|
||||||
|
}
|
||||||
|
// escape sequences, only basic support as of now
|
||||||
|
if (lexer->lookahead == '\\') {
|
||||||
|
return handle_escape_sequence(lexer, token_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lexer->lookahead) {
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handling nested delimiters qq { hello { from { the}}};
|
||||||
|
if (lexer->lookahead == start_delimiter_char) {
|
||||||
|
lexer->result_symbol = token_type;
|
||||||
|
advance(lexer);
|
||||||
|
return scan_nested_delimiters(lexer, token_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
lexer->result_symbol = token_type;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// shouldn't reach here
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool scan_nested_delimiters(TSLexer *lexer, TokenType token_type) {
|
||||||
|
while(lexer->lookahead) {
|
||||||
|
if (lexer->lookahead == get_end_delimiter()) {
|
||||||
|
lexer->result_symbol = token_type;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (lexer->lookahead == start_delimiter_char) {
|
||||||
|
lexer->result_symbol = token_type;
|
||||||
|
advance(lexer);
|
||||||
|
scan_nested_delimiters(lexer, token_type);
|
||||||
|
}
|
||||||
|
else if (lexer->lookahead == '\\') {
|
||||||
|
advance(lexer);
|
||||||
|
advance(lexer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
advance(lexer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void advance(TSLexer *lexer) {
|
||||||
|
lexer->advance(lexer, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void skip(TSLexer *lexer) {
|
||||||
|
lexer->advance(lexer, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_end_delimiter(int32_t start_delimiter) {
|
||||||
|
// round, angle, square, curly
|
||||||
|
is_delimiter_enclosing = true;
|
||||||
|
if (start_delimiter == '(') {
|
||||||
|
end_delimiter_char = ')';
|
||||||
|
}
|
||||||
|
else if (start_delimiter == '<') {
|
||||||
|
end_delimiter_char = '>';
|
||||||
|
}
|
||||||
|
else if (start_delimiter == '[') {
|
||||||
|
end_delimiter_char = ']';
|
||||||
|
}
|
||||||
|
else if (start_delimiter == '{') {
|
||||||
|
end_delimiter_char = '}';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
is_delimiter_enclosing = false;
|
||||||
|
end_delimiter_char = start_delimiter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool process_separator_delimiter(TSLexer *lexer, TokenType separator_token, TokenType end_token) {
|
||||||
|
if (is_separator_delimiter_parsed) {
|
||||||
|
lexer->result_symbol = end_token;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lexer->result_symbol = separator_token;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
|
||||||
|
// if delimiter is {}, (), <>, []
|
||||||
|
if (is_delimiter_enclosing) {
|
||||||
|
run_over_spaces(lexer);
|
||||||
|
|
||||||
|
if (lexer->lookahead == start_delimiter_char) {
|
||||||
|
lexer->result_symbol = separator_token;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
|
||||||
|
is_separator_delimiter_parsed = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
is_separator_delimiter_parsed = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t get_end_delimiter() {
|
||||||
|
return end_delimiter_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give a token type, parses the start delimiter,
|
||||||
|
// and keeps track of it in memory.
|
||||||
|
bool parse_start_delimiter(TSLexer *lexer, TokenType token_type) {
|
||||||
|
run_over_spaces(lexer);
|
||||||
|
|
||||||
|
start_delimiter_char = lexer->lookahead;
|
||||||
|
set_end_delimiter(start_delimiter_char);
|
||||||
|
|
||||||
|
// for substitute and tr/y usecase
|
||||||
|
is_separator_delimiter_parsed = false;
|
||||||
|
|
||||||
|
lexer->result_symbol = token_type;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// runs over spaces like a champ
|
||||||
|
void run_over_spaces(TSLexer *lexer) {
|
||||||
|
while (lexer->lookahead == ' ' || lexer->lookahead == '\t' || lexer->lookahead == '\r' || lexer->lookahead == '\n') {
|
||||||
|
skip(lexer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// runs with the spaces using advance
|
||||||
|
void run_with_spaces(TSLexer *lexer) {
|
||||||
|
while(lexer->lookahead == ' ' || lexer->lookahead == '\t' || lexer->lookahead == '\r' || lexer->lookahead == '\n') {
|
||||||
|
advance(lexer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handle_interpolation(TSLexer *lexer, TokenType surrounding_token) {
|
||||||
|
if (lexer->lookahead == '$') {
|
||||||
|
|
||||||
|
// allow $ to be last character in a regex
|
||||||
|
if (surrounding_token == SEARCH_REPLACE_CONTENT || surrounding_token == REGEX_PATTERN) {
|
||||||
|
advance(lexer);
|
||||||
|
run_with_spaces(lexer);
|
||||||
|
if (lexer->lookahead == get_end_delimiter()) {
|
||||||
|
lexer->result_symbol = surrounding_token;
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handle_escape_sequence(TSLexer *lexer, TokenType surrounding_token) {
|
||||||
|
// escape sequences, only basic support as of now
|
||||||
|
if (lexer->lookahead == '\\') {
|
||||||
|
advance(lexer);
|
||||||
|
// also, self end delimiter will be treated as string
|
||||||
|
if (
|
||||||
|
lexer->lookahead == 't' || lexer->lookahead == 'n' || lexer->lookahead == 'r' || lexer->lookahead == 'f' || lexer->lookahead == 'b' || lexer->lookahead == 'a' || lexer->lookahead == 'e'
|
||||||
|
) {
|
||||||
|
// advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lexer->result_symbol = surrounding_token;
|
||||||
|
advance(lexer);
|
||||||
|
lexer->mark_end(lexer);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handle_nested_delimiters() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t start_delimiter_char;
|
||||||
|
int32_t end_delimiter_char;
|
||||||
|
bool is_separator_delimiter_parsed;
|
||||||
|
bool is_delimiter_enclosing; // is the delimiter {}, <> and same character not //, !!
|
||||||
|
int delimiter_cout = 0;
|
||||||
|
bool reached;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void * tree_sitter_perl_external_scanner_create() {
|
||||||
|
return new Scanner();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tree_sitter_perl_external_scanner_destroy(void *payload) {
|
||||||
|
Scanner *scanner = static_cast<Scanner *>(payload);
|
||||||
|
delete scanner;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned tree_sitter_perl_external_scanner_serialize(
|
||||||
|
void *payload,
|
||||||
|
char *buffer
|
||||||
|
) {
|
||||||
|
Scanner *scanner = static_cast<Scanner *>(payload);
|
||||||
|
return scanner->serialize(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tree_sitter_perl_external_scanner_deserialize(
|
||||||
|
void *payload,
|
||||||
|
const char *buffer,
|
||||||
|
unsigned length
|
||||||
|
) {
|
||||||
|
Scanner *scanner = static_cast<Scanner *>(payload);
|
||||||
|
scanner->deserialize(buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tree_sitter_perl_external_scanner_scan(
|
||||||
|
void *payload,
|
||||||
|
TSLexer *lexer,
|
||||||
|
const bool *valid_symbols
|
||||||
|
) {
|
||||||
|
|
||||||
|
Scanner *scanner = static_cast<Scanner *>(payload);
|
||||||
|
return scanner->scan(lexer, valid_symbols);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,223 @@
|
|||||||
|
#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 **symbol_names;
|
||||||
|
const char **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_
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
=================================================
|
||||||
|
single line comment
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
# I'm a comment and I can be anywhere
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(comments)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
a pound (#) inside a string is a string and not a comment
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $string = "This is a string with # in it";
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable)) (string_double_quoted) (semi_colon))
|
||||||
|
)
|
||||||
@ -0,0 +1,149 @@
|
|||||||
|
=================================================
|
||||||
|
if block with boolean
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
if (1) {
|
||||||
|
print "hello";
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(if_statement (parenthesized_expression (integer))
|
||||||
|
(block
|
||||||
|
(call_expression (identifier) (argument (string_double_quoted))) (semi_colon)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
if else block with boolean
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
if (1) {
|
||||||
|
print "hello";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "else";
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(if_statement (parenthesized_expression (integer))
|
||||||
|
(block
|
||||||
|
(call_expression (identifier) (argument (string_double_quoted))) (semi_colon)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(call_expression (identifier) (argument (string_double_quoted))) (semi_colon)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
Simple while statement
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $i = 0;
|
||||||
|
while ($i < 10) {
|
||||||
|
print "hello $i";
|
||||||
|
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable)) (integer) (semi_colon))
|
||||||
|
(while_statement (empty_parenthesized_expression (binary_expression (scalar_variable) (integer)))
|
||||||
|
(block
|
||||||
|
(call_expression (identifier) (argument (string_double_quoted (interpolation (scalar_variable))))) (semi_colon)
|
||||||
|
(unary_expression (scalar_variable)) (semi_colon)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
while statement with label
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $i = 0;
|
||||||
|
MEOW: while ($i < 10) {
|
||||||
|
print "hello $i";
|
||||||
|
|
||||||
|
next MEOW;
|
||||||
|
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable)) (integer) (semi_colon))
|
||||||
|
(while_statement (identifier) (empty_parenthesized_expression (binary_expression (scalar_variable) (integer)))
|
||||||
|
(block
|
||||||
|
(call_expression (identifier) (argument (string_double_quoted (interpolation (scalar_variable))))) (semi_colon) (loop_control_statement (loop_control_keyword) (identifier) (semi_colon)) (unary_expression (scalar_variable)) (semi_colon))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
single line for loop
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my @array = (1, 3, 4);
|
||||||
|
print "in a loop" for @array;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (array_variable)) (array (integer) (integer) (integer)) (semi_colon))
|
||||||
|
(single_line_statement (call_expression (identifier) (argument (string_double_quoted))) (for_simple_statement (array_variable) (semi_colon)))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
simple for loop TODO: this is failing
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
for (my $i=1; $i < 10; $i++) {
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(for_statement_1 (binary_expression (call_expression (identifier) (argument (scalar_variable))) (integer)) (semi_colon) (binary_expression (scalar_variable) (integer)) (semi_colon) (unary_expression (scalar_variable))
|
||||||
|
(block)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
for ever loop
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
print "hello";
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(for_statement_1 (semi_colon) (semi_colon)
|
||||||
|
(block
|
||||||
|
(call_expression (identifier) (argument (string_double_quoted))) (semi_colon)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
foreach loop
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
foreach my $single (@array) {
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(foreach_statement (scope) (scalar_variable) (array_variable)
|
||||||
|
(block)
|
||||||
|
)
|
||||||
|
)
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
=================================================
|
||||||
|
switch feature
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
use feature "switch";
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file (use_no_feature_statement (string_double_quoted) (semi_colon)))
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
multi features
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
use feature qw(switch say);
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file (use_no_feature_statement (word_list_qw (list_item) (list_item)) (semi_colon)))
|
||||||
@ -0,0 +1,204 @@
|
|||||||
|
=================================================
|
||||||
|
scalar declaration
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $a;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration
|
||||||
|
(scalar_variable)
|
||||||
|
) (semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
scalar declaration with initialization
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $a = 3;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration
|
||||||
|
(scalar_variable)) (integer) (semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
multi declaration with initialization
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my ($self, $args) = @_;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope)
|
||||||
|
(multi_var_declaration
|
||||||
|
(variable_declarator (scalar_variable)) (variable_declarator (scalar_variable))
|
||||||
|
) (special_array_variable) (semi_colon)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
array declaration
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my @array;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration
|
||||||
|
(array_variable)
|
||||||
|
) (semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
array declaration with initialization
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my @array = ('meow', 'woof', 'burp');
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration
|
||||||
|
(array_variable)) (array (string_single_quoted) (string_single_quoted) (string_single_quoted)) (semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
hash ref with initialization
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $hash = {
|
||||||
|
'cat' => 'meow',
|
||||||
|
"cow" => 'moo',
|
||||||
|
dog => 'woof',
|
||||||
|
};
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable))
|
||||||
|
(hash_ref
|
||||||
|
(string_single_quoted) (hash_arrow_operator) (string_single_quoted)
|
||||||
|
(string_double_quoted) (hash_arrow_operator) (string_single_quoted)
|
||||||
|
(bareword) (hash_arrow_operator) (string_single_quoted))
|
||||||
|
(semi_colon)))
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
use statement
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(use_no_statement (package_name (identifier) (identifier)) (semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
no statement
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
no strict 'refs';
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(use_no_statement (package_name (identifier)) (string_single_quoted) (semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
require statement
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
require Data::Dumper;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(require_statement (package_name (identifier) (identifier)) (semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
single line comment
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
# this is a single line comment
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(comments)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
length of an array
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
$#array;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(scalar_variable) (semi_colon)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
single quoted string with # in it
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $string = 'I have # in me';
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable)) (string_single_quoted) (semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
single quoted string with the only one supported escaping
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $string = 'I have \' escaping in me';
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable)) (string_single_quoted) (semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
Double quoted string with escape sequence
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
"this is a string \n in next line at the end";
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(string_double_quoted (escape_sequence)) (semi_colon)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
<STDIN>
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
while (<>) {}
|
||||||
|
my $fh = \*STDIN;
|
||||||
|
my $line = <$fh>;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(while_statement (empty_parenthesized_expression (standard_input))
|
||||||
|
(block)
|
||||||
|
)
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable)) (standard_input) (semi_colon))
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable)) (standard_input_to_variable (scalar_variable)) (semi_colon))
|
||||||
|
)
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
=================================================
|
||||||
|
method invocation 1
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $output = BaseModule::YeaThis->hello('first', {
|
||||||
|
hello => 'beautiful'
|
||||||
|
});
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable))
|
||||||
|
(method_invocation (package_name (identifier) (identifier)) (arrow_operator) (identifier)
|
||||||
|
(parenthesized_argument (argument (string_single_quoted) (hash_ref (bareword) (hash_arrow_operator) (string_single_quoted)))))
|
||||||
|
(semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
method invocation 2
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $output = BaseModule->new();
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable))
|
||||||
|
(method_invocation (identifier) (arrow_operator) (identifier) (empty_parenthesized_argument)) (semi_colon))
|
||||||
|
)
|
||||||
@ -0,0 +1,170 @@
|
|||||||
|
=================================================
|
||||||
|
Interpolate only $ and @ variable and not %hash or object reference TODO: fix this
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
qq {hello $meow print("dsfsdf) %hash};
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(string_qq_quoted
|
||||||
|
(start_delimiter)
|
||||||
|
(interpolation (scalar_variable))
|
||||||
|
(end_delimiter))
|
||||||
|
(semi_colon)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
qq //
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
qq /im inside another delimiter/;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(string_qq_quoted (start_delimiter) (end_delimiter)) (semi_colon)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
qq '' interpolate
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
qq 'this should $interpolate, yes';
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(string_qq_quoted (start_delimiter) (interpolation (scalar_variable)) (end_delimiter)) (semi_colon)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
q{} string
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $string = q{im a non interpolated string};
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable)) (string_q_quoted) (semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
qx command
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $string = q{im a non interpolated string};
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable)) (string_q_quoted) (semi_colon))
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
qw command
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my @array = qw /
|
||||||
|
PUBG
|
||||||
|
EVENING
|
||||||
|
BIO_SHOCK_INFINITY
|
||||||
|
/;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration
|
||||||
|
(scope) (single_var_declaration (array_variable)) (word_list_qw (list_item) (list_item) (list_item)) (semi_colon)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
m matcher operator
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
$string =~ m/Simple/is;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(binary_expression
|
||||||
|
(scalar_variable) (patter_matcher_m (start_delimiter) (end_delimiter) (regex_option))
|
||||||
|
) (semi_colon)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
m matcher operator - $ at the end shouldn't interpolate
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $x = 'shru';
|
||||||
|
if ($x =~ m/u$/) {
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable)) (string_single_quoted) (semi_colon))
|
||||||
|
(if_statement
|
||||||
|
(parenthesized_expression (binary_expression (scalar_variable) (patter_matcher_m (start_delimiter) (end_delimiter))))
|
||||||
|
(block)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
qr regex operator
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $rex = qr/my.STRING/is;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration
|
||||||
|
(scope) (single_var_declaration (scalar_variable)) (regex_pattern_qr (start_delimiter) (end_delimiter) (regex_option)) (semi_colon)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
s regex substitution
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
$subs =~ s/my.STRING/foo/is;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(binary_expression
|
||||||
|
(scalar_variable)
|
||||||
|
(substitution_pattern_s (start_delimiter) (separator_delimiter) (end_delimiter) (regex_option_for_substitution))) (semi_colon)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
s regex substitution - no replace content
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
$subs =~ s/search//is;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(binary_expression
|
||||||
|
(scalar_variable)
|
||||||
|
(substitution_pattern_s (start_delimiter) (separator_delimiter) (end_delimiter) (regex_option_for_substitution))) (semi_colon)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
tr// or y// transliteration
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $subs =~ tr{bar}{foo}cs;
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration
|
||||||
|
(scope) (single_var_declaration (scalar_variable))
|
||||||
|
(unary_expression (transliteration_tr_or_y (start_delimiter) (separator_delimiter) (end_delimiter) (regex_option_for_transliteration))) (semi_colon)
|
||||||
|
)
|
||||||
|
)
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
=================================================
|
||||||
|
ellipsis statement
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
sub foo { ... }
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(function_definition (identifier)
|
||||||
|
(block
|
||||||
|
(ellipsis_statement)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
constant
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
use constant SOUL_MATE => 'SCORPIO';
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(use_constant_statement (identifier) (string_single_quoted) (semi_colon))
|
||||||
|
)
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
=================================================
|
||||||
|
Subroutine with empty block
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
sub hello {
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(function_definition (identifier)
|
||||||
|
(block)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
Subroutine call / function call
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
hello();
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(call_expression
|
||||||
|
function_name: (identifier) args: (empty_parenthesized_argument)) (semi_colon)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
Subroutine with arrow notation
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
my $result = GetSalesforceTemplateInfo($dbh)->{$args->{ALOHA}}->{'NAMASTE'};
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(variable_declaration (scope) (single_var_declaration (scalar_variable))
|
||||||
|
(hash_access_variable
|
||||||
|
(hash_access_variable (call_expression (identifier) (argument (scalar_variable)))
|
||||||
|
(hash_access_variable (scalar_variable) (bareword))) (string_single_quoted)) (semi_colon)))
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
Subroutine calling another subroutine without params
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
print Dumper %{$args};
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(call_expression (identifier) (argument
|
||||||
|
(call_expression (identifier) (argument (hash_dereference (scalar_variable)))))) (semi_colon)
|
||||||
|
)
|
||||||
|
|
||||||
|
=================================================
|
||||||
|
Subroutine with CODE signature
|
||||||
|
=================================================
|
||||||
|
|
||||||
|
sub Run (&) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
(source_file
|
||||||
|
(function_definition (identifier) (function_prototype (prototype))
|
||||||
|
(block)
|
||||||
|
)
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue