summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Hatch <tim@timhatch.com>2014-04-14 20:10:43 -0400
committerTim Hatch <tim@timhatch.com>2014-04-14 20:10:43 -0400
commitc852aa1e65a7175a4d62d321b9b18f70e4e6b93a (patch)
treed85fa6888fe28661298e4d2dd0afa3f7d6afd88a
parentd85343792ab32ad0b737bfc17208d7239863e73a (diff)
parent11442f9ec452df6f12706b6e5ad101a09f1e7c14 (diff)
downloadpygments-c852aa1e65a7175a4d62d321b9b18f70e4e6b93a.tar.gz
Merged in jlafon/pygments-main-redo-247 (pull request #318)
-rw-r--r--pygments/lexers/web.py25
-rw-r--r--tests/examplefiles/test.php4
2 files changed, 19 insertions, 10 deletions
diff --git a/pygments/lexers/web.py b/pygments/lexers/web.py
index 7d3073f1..f388f611 100644
--- a/pygments/lexers/web.py
+++ b/pygments/lexers/web.py
@@ -799,6 +799,13 @@ class PhpLexer(RegexLexer):
filenames = ['*.php', '*.php[345]', '*.inc']
mimetypes = ['text/x-php']
+ # Note that a backslash is included in the following two patterns
+ # PHP uses a backslash as a namespace separator
+ _ident_char = r'[\\_a-zA-Z0-9]|[^\x00-\x7f]'
+ _ident_begin = r'(?:[\\_a-zA-Z]|[^\x00-\x7f])'
+ _ident_end = r'(?:' + _ident_char + ')*'
+ _ident_inner = _ident_begin + _ident_end
+
flags = re.IGNORECASE | re.DOTALL | re.MULTILINE
tokens = {
'root': [
@@ -808,7 +815,7 @@ class PhpLexer(RegexLexer):
],
'php': [
(r'\?>', Comment.Preproc, '#pop'),
- (r'<<<(\'?)([a-zA-Z_][a-zA-Z0-9_]*)\1\n.*?\n\2\;?\n', String),
+ (r'<<<(\'?)(' + _ident_inner + ')\1\n.*?\n\2\;?\n', String),
(r'\s+', Text),
(r'#.*?\n', Comment.Single),
(r'//.*?\n', Comment.Single),
@@ -817,7 +824,7 @@ class PhpLexer(RegexLexer):
(r'/\*\*/', Comment.Multiline),
(r'/\*\*.*?\*/', String.Doc),
(r'/\*.*?\*/', Comment.Multiline),
- (r'(->|::)(\s*)([a-zA-Z_][a-zA-Z0-9_]*)',
+ (r'(->|::)(\s*)(' + _ident_inner + ')',
bygroups(Operator, Text, Name.Attribute)),
(r'[~!%^&*+=|:.<>/?@-]+', Operator),
(r'[\[\]{}();,]+', Punctuation),
@@ -825,7 +832,7 @@ class PhpLexer(RegexLexer):
(r'(function)(\s*)(?=\()', bygroups(Keyword, Text)),
(r'(function)(\s+)(&?)(\s*)',
bygroups(Keyword, Text, Operator, Text), 'functionname'),
- (r'(const)(\s+)([a-zA-Z_][a-zA-Z0-9_]*)',
+ (r'(const)(\s+)(' + _ident_inner + ')',
bygroups(Keyword, Text, Name.Constant)),
(r'(and|E_PARSE|old_function|E_ERROR|or|as|E_WARNING|parent|'
r'eval|PHP_OS|break|exit|case|extends|PHP_VERSION|cfunction|'
@@ -839,9 +846,9 @@ class PhpLexer(RegexLexer):
r'catch|throw|this|use|namespace|trait|yield|'
r'finally)\b', Keyword),
(r'(true|false|null)\b', Keyword.Constant),
- (r'\$\{\$+[a-zA-Z_][a-zA-Z0-9_]*\}', Name.Variable),
- (r'\$+[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable),
- (r'[\\a-zA-Z_][\\a-zA-Z0-9_]*', Name.Other),
+ (r'\$\{\$+' + _ident_inner + '\}', Name.Variable),
+ (r'\$+' + _ident_inner, Name.Variable),
+ (_ident_inner, Name.Other),
(r'(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float),
(r'\d+[eE][+-]?[0-9]+', Number.Float),
(r'0[0-7]+', Number.Oct),
@@ -853,16 +860,16 @@ class PhpLexer(RegexLexer):
(r'"', String.Double, 'string'),
],
'classname': [
- (r'[a-zA-Z_][\\a-zA-Z0-9_]*', Name.Class, '#pop')
+ (_ident_inner, Name.Class, '#pop')
],
'functionname': [
- (r'[a-zA-Z_][a-zA-Z0-9_]*', Name.Function, '#pop')
+ (_ident_inner, Name.Function, '#pop')
],
'string': [
(r'"', String.Double, '#pop'),
(r'[^{$"\\]+', String.Double),
(r'\\([nrt\"$\\]|[0-7]{1,3}|x[0-9A-Fa-f]{1,2})', String.Escape),
- (r'\$[a-zA-Z_][a-zA-Z0-9_]*(\[\S+?\]|->[a-zA-Z_][a-zA-Z0-9_]*)?',
+ (r'\$' + _ident_inner + '(\[\S+?\]|->' + _ident_inner + ')?',
String.Interpol),
(r'(\{\$\{)(.*?)(\}\})',
bygroups(String.Interpol, using(this, _startinline=True),
diff --git a/tests/examplefiles/test.php b/tests/examplefiles/test.php
index 97e21f73..218892fe 100644
--- a/tests/examplefiles/test.php
+++ b/tests/examplefiles/test.php
@@ -1,5 +1,7 @@
<?php
+$disapproval_ಠ_ಠ_of_php = 'unicode var';
+
$test = function($a) { $lambda = 1; }
/**
@@ -16,7 +18,7 @@ if(!defined('UNLOCK') || !UNLOCK)
// Load the parent archive class
require_once(ROOT_PATH.'/classes/archive.class.php');
-class Zip\Zipp {
+class Zip\Zippಠ_ಠ_ {
}