Skip to content

Commit

Permalink
enh(zephir) almost complete rework of the zephir grammar (highlightjs…
Browse files Browse the repository at this point in the history
…#2387)

* (chore) zephir grammar cleanups and more

The original grammar was lifted from PHP and is inaccurate in many ways.
  • Loading branch information
joshgoebel authored and taufik-nurrohman committed Feb 18, 2020
1 parent 1364124 commit 9014cad
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 32 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -15,6 +15,7 @@ Core Changes:

Language Improvements:

- enh(zephir) almost complete rework of the zephir grammar (#2387) [Josh Goebel][]
- (markdown) much improved code block support (#2382) [Josh Goebel][]
- (markdown) improve bold/italic nesting (#2382) [Josh Goebel][]
- enh(csharp) Support `where` keyword as class constraint (#2378) [Josh Goebel][]
Expand Down
67 changes: 35 additions & 32 deletions src/languages/zephir.js
Expand Up @@ -10,33 +10,44 @@ function(hljs) {
className: 'string',
contains: [hljs.BACKSLASH_ESCAPE],
variants: [
{
begin: 'b"', end: '"'
},
{
begin: 'b\'', end: '\''
},
hljs.inherit(hljs.APOS_STRING_MODE, {illegal: null}),
hljs.inherit(hljs.QUOTE_STRING_MODE, {illegal: null})
]
};
var TITLE_MODE = hljs.UNDERSCORE_TITLE_MODE;
var NUMBER = {variants: [hljs.BINARY_NUMBER_MODE, hljs.C_NUMBER_MODE]};
var KEYWORDS =
// classes and objects
'namespace class interface use extends ' +
'function return ' +
'abstract final public protected private static deprecated ' +
// error handling
'throw try catch Exception ' +
// keyword-ish things their website does NOT seem to highlight (in their own snippets)
// 'typeof fetch in ' +
// operators/helpers
'echo empty isset instanceof unset ' +
// assignment/variables
'let var new const self ' +
// control
'require ' +
'if else elseif switch case default ' +
'do while loop for continue break ' +
'likely unlikely ' +
// magic constants
// https://github.com/phalcon/zephir/blob/master/Library/Expression/Constants.php
'__LINE__ __FILE__ __DIR__ __FUNCTION__ __CLASS__ __TRAIT__ __METHOD__ __NAMESPACE__ ' +
// types - https://docs.zephir-lang.com/0.12/en/types
'array boolean float double integer object resource string ' +
'char long unsigned bool int uint ulong uchar ' +
// built-ins
'true false null undefined';

return {
aliases: ['zep'],
case_insensitive: true,
keywords:
'and include_once list abstract global private echo interface as static endswitch ' +
'array null if endwhile or const for endforeach self var let while isset public ' +
'protected exit foreach throw elseif include __FILE__ empty require_once do xor ' +
'return parent clone use __CLASS__ __LINE__ else break print eval new ' +
'catch __METHOD__ case exception default die require __FUNCTION__ ' +
'enddeclare final try switch continue endfor endif declare unset true false ' +
'trait goto instanceof insteadof __DIR__ __NAMESPACE__ ' +
'yield finally int uint long ulong char uchar double float bool boolean string' +
'likely unlikely',
keywords: KEYWORDS,
contains: [
hljs.C_LINE_COMMENT_MODE,
hljs.HASH_COMMENT_MODE,
hljs.COMMENT(
'/\\*',
'\\*/',
Expand All @@ -49,15 +60,6 @@ function(hljs) {
]
}
),
hljs.COMMENT(
'__halt_compiler.+?;',
false,
{
endsWithParent: true,
keywords: '__halt_compiler',
lexemes: hljs.UNDERSCORE_IDENT_RE
}
),
{
className: 'string',
begin: '<<<[\'"]?\\w+[\'"]?$', end: '^\\w+;',
Expand All @@ -69,13 +71,14 @@ function(hljs) {
},
{
className: 'function',
beginKeywords: 'function', end: /[;{]/, excludeEnd: true,
beginKeywords: 'function fn', end: /[;{]/, excludeEnd: true,
illegal: '\\$|\\[|%',
contains: [
hljs.UNDERSCORE_TITLE_MODE,
TITLE_MODE,
{
className: 'params',
begin: '\\(', end: '\\)',
keywords: KEYWORDS,
contains: [
'self',
hljs.C_BLOCK_COMMENT_MODE,
Expand All @@ -91,17 +94,17 @@ function(hljs) {
illegal: /[:\(\$"]/,
contains: [
{beginKeywords: 'extends implements'},
hljs.UNDERSCORE_TITLE_MODE
TITLE_MODE
]
},
{
beginKeywords: 'namespace', end: ';',
illegal: /[\.']/,
contains: [hljs.UNDERSCORE_TITLE_MODE]
contains: [TITLE_MODE]
},
{
beginKeywords: 'use', end: ';',
contains: [hljs.UNDERSCORE_TITLE_MODE]
contains: [TITLE_MODE]
},
{
begin: '=>' // No markup, just a relevance booster
Expand Down
55 changes: 55 additions & 0 deletions test/markup/zephir/default.expect.txt
@@ -0,0 +1,55 @@
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">testBefore</span><span class="hljs-params">(&lt;Test&gt; a, <span class="hljs-keyword">var</span> b = <span class="hljs-number">5</span>, <span class="hljs-keyword">int</span> c = <span class="hljs-number">10</span>)</span>
</span>{
a-&gt;method1();

<span class="hljs-keyword">return</span> b + c;
}

<span class="hljs-keyword">namespace</span> <span class="hljs-title">Test</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">RuntimeException</span> <span class="hljs-title">as</span> <span class="hljs-title">RE</span>;

<span class="hljs-comment">/**
* Example comment
*/</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Test</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">CustomClass</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">TestInterface</span>
</span>{
<span class="hljs-keyword">const</span> C1 = <span class="hljs-keyword">null</span>;

<span class="hljs-comment">// Magic constant: http://php.net/manual/ru/language.constants.predefined.php</span>
<span class="hljs-keyword">const</span> className = <span class="hljs-keyword">__CLASS__</span>;

<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">method1</span><span class="hljs-params">()</span>
</span>{
<span class="hljs-keyword">int</span> a = <span class="hljs-number">1</span>, b = <span class="hljs-number">2</span>;
<span class="hljs-keyword">return</span> a + b;
}

<span class="hljs-comment">// See fn is allowed like shortcut</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">method2</span><span class="hljs-params">()</span> -&gt; &lt;<span class="hljs-title">Test</span>&gt;
</span>{
call_user_func(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{ <span class="hljs-keyword">echo</span> <span class="hljs-string">"hello"</span>; });


[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]-&gt;walk(
<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(<span class="hljs-keyword">int</span>! x)</span> </span>{
<span class="hljs-keyword">return</span> x * x;
}
);

[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]-&gt;walk(
<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(_, <span class="hljs-keyword">int</span> key)</span> </span>{ <span class="hljs-keyword">echo</span> key; }
);

<span class="hljs-keyword">array</span> input = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>];

input-&gt;walk(
<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(_, <span class="hljs-keyword">int</span> key)</span> </span>{ <span class="hljs-keyword">echo</span> key; }
);


input-&gt;map(x =&gt; x * x);

<span class="hljs-keyword">return</span> this;
}
}
55 changes: 55 additions & 0 deletions test/markup/zephir/default.txt
@@ -0,0 +1,55 @@
function testBefore(<Test> a, var b = 5, int c = 10)
{
a->method1();

return b + c;
}

namespace Test;

use RuntimeException as RE;

/**
* Example comment
*/
class Test extends CustomClass implements TestInterface
{
const C1 = null;

// Magic constant: http://php.net/manual/ru/language.constants.predefined.php
const className = __CLASS__;

public function method1()
{
int a = 1, b = 2;
return a + b;
}

// See fn is allowed like shortcut
public fn method2() -> <Test>
{
call_user_func(function() { echo "hello"; });


[1, 2, 3, 4, 5]->walk(
function(int! x) {
return x * x;
}
);

[1, 2, 3, 4, 5]->walk(
function(_, int key) { echo key; }
);

array input = [1, 2, 3, 4, 5];

input->walk(
function(_, int key) { echo key; }
);


input->map(x => x * x);

return this;
}
}

0 comments on commit 9014cad

Please sign in to comment.