[vala] Add experimental support for regular expression literals
- From: Jürg Billeter <juergbi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] Add experimental support for regular expression literals
- Date: Thu, 25 Mar 2010 09:44:45 +0000 (UTC)
commit 1afe020286302dcce26abc19ed559da05d21e3eb
Author: Jukka-Pekka Iivonen <jp0409 jippii fi>
Date: Wed Mar 24 10:07:32 2010 +0100
Add experimental support for regular expression literals
Fixes bug 607702.
codegen/valaccodebasemodule.vala | 39 ++++++++
codegen/valaccodegenerator.vala | 5 +
codegen/valaccodemodule.vala | 4 +
tests/Makefile.am | 1 +
tests/objects/regex.vala | 107 +++++++++++++++++++++
vala/Makefile.am | 1 +
vala/valacodevisitor.vala | 9 ++
vala/valaparser.vala | 20 ++++
vala/valaregexliteral.vala | 89 ++++++++++++++++++
vala/valascanner.vala | 191 +++++++++++++++++++++++++++++++++++++-
vala/valasemanticanalyzer.vala | 2 +
vala/valatokentype.vala | 6 +
12 files changed, 469 insertions(+), 5 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 1e7175d..f839654 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -150,6 +150,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
Set<string> reserved_identifiers;
public int next_temp_var_id = 0;
+ public int next_regex_id = 0;
public bool in_creation_method { get { return current_method is CreationMethod; } }
public bool in_constructor = false;
public bool in_static_or_class_context = false;
@@ -178,6 +179,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
public DataType int64_type;
public DataType uint64_type;
public DataType string_type;
+ public DataType regex_type;
public DataType float_type;
public DataType double_type;
public TypeSymbol gtype_type;
@@ -313,6 +315,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
float_type = new FloatingType ((Struct) root_symbol.scope.lookup ("float"));
double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double"));
string_type = new ObjectType ((Class) root_symbol.scope.lookup ("string"));
+ regex_type = new ObjectType ((Class) root_symbol.scope.lookup ("GLib").scope.lookup ("Regex"));
var unichar_struct = (Struct) root_symbol.scope.lookup ("unichar");
if (unichar_struct != null) {
@@ -3548,6 +3551,42 @@ internal class Vala.CCodeBaseModule : CCodeModule {
expr.ccodenode = new CCodeConstant.string (expr.value);
}
+ public override void visit_regex_literal (RegexLiteral expr) {
+ string[] parts = expr.value.split ("/", 3);
+ string re = parts[2].escape ("");
+ string flags = "0";
+
+ if (parts[1].contains ("i")) {
+ flags += " | G_REGEX_CASELESS";
+ }
+ if (parts[1].contains ("m")) {
+ flags += " | G_REGEX_MULTILINE";
+ }
+ if (parts[1].contains ("s")) {
+ flags += " | G_REGEX_DOTALL";
+ }
+ if (parts[1].contains ("x")) {
+ flags += " | G_REGEX_EXTENDED";
+ }
+
+ var regex_var = get_temp_variable (regex_type, true, expr, false);
+ expr.temp_vars.add (regex_var);
+
+ var cdecl = new CCodeDeclaration ("GRegex*");
+
+ var cname = regex_var.name + "regex_" + next_regex_id.to_string ();
+ this.next_regex_id++;
+
+ cdecl.add_declarator (new CCodeVariableDeclarator (cname + " = NULL"));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+
+ var regex_const = new CCodeConstant ("(%s == NULL) ? (%s = g_regex_new (\"".printf (cname, cname)
+ + re + "\", " + flags + ", 0, NULL)) : %s".printf (cname));
+
+ source_declarations.add_constant_declaration (cdecl);
+ expr.ccodenode = regex_const;
+ }
+
public override void visit_null_literal (NullLiteral expr) {
if (context.profile != Profile.GOBJECT) {
source_declarations.add_include ("stddef.h");
diff --git a/codegen/valaccodegenerator.vala b/codegen/valaccodegenerator.vala
index f8af697..e7472c2 100644
--- a/codegen/valaccodegenerator.vala
+++ b/codegen/valaccodegenerator.vala
@@ -280,6 +280,11 @@ public class Vala.CCodeGenerator : CodeGenerator {
head.visit_tuple (expr);
}
+ public override void visit_regex_literal (RegexLiteral expr) {
+ head.visit_regex_literal (expr);
+ }
+
+
public override void visit_null_literal (NullLiteral expr) {
head.visit_null_literal (expr);
}
diff --git a/codegen/valaccodemodule.vala b/codegen/valaccodemodule.vala
index 523ac08..1afeac2 100644
--- a/codegen/valaccodemodule.vala
+++ b/codegen/valaccodemodule.vala
@@ -259,6 +259,10 @@ public abstract class Vala.CCodeModule {
next.visit_tuple (expr);
}
+ public virtual void visit_regex_literal (RegexLiteral re) {
+ next.visit_regex_literal (re);
+ }
+
public virtual void visit_null_literal (NullLiteral expr) {
next.visit_null_literal (expr);
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 04e3980..929be7a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -55,6 +55,7 @@ TESTS = \
objects/interfaces.vala \
objects/methods.vala \
objects/properties.vala \
+ objects/regex.vala \
objects/signals.vala \
objects/test-025.vala \
objects/test-026.vala \
diff --git a/tests/objects/regex.vala b/tests/objects/regex.vala
new file mode 100644
index 0000000..1c517f3
--- /dev/null
+++ b/tests/objects/regex.vala
@@ -0,0 +1,107 @@
+using GLib;
+
+
+static Regex get_from_array (int index)
+{
+ Regex[] arr = {
+ /(\d+\.\d+\.\d+)/,
+ /(\d+)\.\d+\.\d+/,
+ /\d+\.(\d+)\.\d+/,
+ /(\d+)\.\d+\.(\d+)/
+ };
+
+ assert (0 <= index <= 3);
+ return arr[index];
+}
+
+static Regex get_fixed ()
+{
+ return /(is.*ip)/;
+}
+
+class Test : Object {
+ public signal void regexTest (string str);
+ public void run (string s)
+ {
+ regexTest (s);
+ }
+}
+
+void main ()
+{
+ MatchInfo info;
+
+ // Simple greedy regular expression matching, regex received as a function return value.
+ var str1 = "mississippi";
+ if (get_fixed ().match (str1, 0, out info)) {
+ stdout.printf ("Part of %s is '%s'...\n", str1, info.fetch (1));
+ } else {
+ stdout.printf ("Did not match at all.\n");
+ }
+
+ // Match caseless.
+ var str2 = "demonStration";
+ if (/mon(str.*o)n/i.match (str2, 0, out info)) {
+ stdout.printf ("Part of %s is '%s'...\n", str2, info.fetch (1));
+ } else {
+ stdout.printf ("%s did not match at all.\n", str2);
+ }
+
+ // Match and pick substrings.
+ var ts = "Time: 10:42:12";
+ if (/Time: (..):(..):(..)/.match (ts, 0, out info)) {
+ stdout.printf ("%s\n\thours = %s\n\tminutes = %s\n\tseconds = %s\n\n", ts, info.fetch (1), info.fetch (2), info.fetch (3));
+ }
+
+ // Replace demo: word swapping
+ try {
+ var str = "apple grape";
+ stdout.printf ("'%s' becomes '%s'\n", str, /^([^ ]*) *([^ ]*)/.replace (str, -1, 0, """\2 \1"""));
+ } catch (RegexError err) {
+ // Replacing still needs exception catching
+ message (err.message);
+ }
+
+ // Regex literals in an array
+ for (int i=0; i<4; i++) {
+ if (get_from_array (i).match ("23.3.2010", 0, out info)) {
+ stdout.printf ("Round %d: %s\n", i, info.fetch (1));
+ }
+ }
+
+ // ??-operator
+ Regex? r = null;
+ Regex? r1 = null;
+ Regex? r2 = null;
+
+ r = r1 ?? r2 ?? /match (this)/i;
+ if (r.match ("match THIS", 0, out info)) {
+ stdout.printf ("Match: %s\n", info.fetch (1));
+ }
+
+ // Escape sequences
+ if (/\.\+\(\)\-\?\/\"\$\[\]\*\^/.match (".+()-?/\"$[]*^")) {
+ stdout.printf ("Matches\n");
+ } else {
+ stdout.printf ("Does not match.\n");
+ }
+
+ // Lambda and closure test
+ Regex? rc = /foo(bar)/i;
+ var test = new Test ();
+ test.regexTest.connect ((s) => {
+ if (rc.match (s, 0, out info)) {
+ stdout.printf ("Lambda (closure var.): %s -> %s\n", s, info.fetch (1));
+ } else {
+ stdout.printf ("Does not match.\n");
+ }
+ if (/foo(bar)/i.match (s, 0, out info)) {
+ stdout.printf ("Lambda (lit.): %s -> %s\n", s, info.fetch (1));
+ } else {
+ stdout.printf ("Does not match.\n");
+ }
+ });
+ test.run ("fooBar");
+ test.run ("foobAr");
+}
+
diff --git a/vala/Makefile.am b/vala/Makefile.am
index aa0b861..f6203a9 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -118,6 +118,7 @@ libvalacore_la_VALASOURCES = \
valarealliteral.vala \
valareferencetransferexpression.vala \
valareferencetype.vala \
+ valaregexliteral.vala \
valareport.vala \
valareturnstatement.vala \
valascanner.vala \
diff --git a/vala/valacodevisitor.vala b/vala/valacodevisitor.vala
index 55f87d7..5f6a0c8 100644
--- a/vala/valacodevisitor.vala
+++ b/vala/valacodevisitor.vala
@@ -469,6 +469,15 @@ public abstract class Vala.CodeVisitor {
}
/**
+ * Visit operation called for regex literals.
+ *
+ * @param lit a regex literal
+ */
+ public virtual void visit_regex_literal (RegexLiteral lit) {
+ }
+
+
+ /**
* Visit operation called for string literals.
*
* @param lit a string literal
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index c9563c0..15ae81b 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -290,6 +290,13 @@ public class Vala.Parser : CodeVisitor {
Report.error (lit.source_reference, "invalid character literal");
}
return lit;
+ case TokenType.REGEX_LITERAL:
+ next ();
+ string match_part = get_last_string ();
+ SourceReference src_begin = get_src (begin);
+ expect (TokenType.CLOSE_REGEX_LITERAL);
+ string close_token = get_last_string ();
+ return new RegexLiteral ("%s/%s".printf (close_token, match_part), src_begin);
case TokenType.STRING_LITERAL:
next ();
return new StringLiteral (get_last_string (), get_src (begin));
@@ -560,6 +567,7 @@ public class Vala.Parser : CodeVisitor {
case TokenType.REAL_LITERAL:
case TokenType.CHARACTER_LITERAL:
case TokenType.STRING_LITERAL:
+ case TokenType.REGEX_LITERAL:
case TokenType.TEMPLATE_STRING_LITERAL:
case TokenType.VERBATIM_STRING_LITERAL:
case TokenType.NULL:
@@ -585,6 +593,9 @@ public class Vala.Parser : CodeVisitor {
case TokenType.OPEN_TEMPLATE:
expr = parse_template ();
break;
+ case TokenType.OPEN_REGEX_LITERAL:
+ expr = parse_regex_literal ();
+ break;
case TokenType.THIS:
expr = parse_this_access ();
break;
@@ -694,6 +705,14 @@ public class Vala.Parser : CodeVisitor {
return template;
}
+ Expression parse_regex_literal () throws ParseError {
+ expect (TokenType.OPEN_REGEX_LITERAL);
+
+ var expr = parse_literal ();
+
+ return expr;
+ }
+
Expression parse_member_access (SourceLocation begin, Expression inner) throws ParseError {
expect (TokenType.DOT);
string id = parse_identifier ();
@@ -985,6 +1004,7 @@ public class Vala.Parser : CodeVisitor {
case TokenType.STRING_LITERAL:
case TokenType.TEMPLATE_STRING_LITERAL:
case TokenType.VERBATIM_STRING_LITERAL:
+ case TokenType.REGEX_LITERAL:
case TokenType.NULL:
case TokenType.THIS:
case TokenType.BASE:
diff --git a/vala/valaregexliteral.vala b/vala/valaregexliteral.vala
new file mode 100644
index 0000000..eb1edd5
--- /dev/null
+++ b/vala/valaregexliteral.vala
@@ -0,0 +1,89 @@
+/* valaregexliteral.vala
+ *
+ * Copyright (C) 2010 Jukka-Pekka Iivonen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Jukka-Pekka Iivonen <jp0409 jippii fi>
+ */
+
+using GLib;
+
+/**
+ * Represents a regular expression literal in the source code.
+ */
+public class Vala.RegexLiteral : Literal {
+ /**
+ * The literal value.
+ */
+ public string value { get; set; }
+
+ /**
+ * Creates a new regular expression literal.
+ *
+ * @param s the literal value
+ * @param source reference to source code
+ * @return newly created string literal
+ */
+ public RegexLiteral (string value, SourceReference? source_reference = null) {
+ this.value = value;
+ this.source_reference = source_reference;
+ }
+
+ public override void accept (CodeVisitor visitor) {
+ visitor.visit_regex_literal (this);
+
+ visitor.visit_expression (this);
+ }
+
+ public override bool is_pure () {
+ return true;
+ }
+
+ public override bool is_non_null () {
+ return true;
+ }
+
+ public override string to_string () {
+ return value;
+ }
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ if (!analyzer.context.experimental) {
+ Report.warning (source_reference, "regular expression literals are experimental");
+ }
+
+ try {
+ var regex = new GLib.Regex (value);
+ if (regex != null) { /* Regex is valid. */ }
+ } catch (RegexError err) {
+ error = true;
+ Report.error (source_reference, "Invalid regular expression `%s'.".printf (value));
+ return false;
+ }
+
+ value_type = analyzer.regex_type.copy ();
+
+ return !error;
+ }
+}
+
diff --git a/vala/valascanner.vala b/vala/valascanner.vala
index 744dcf1..3a05b5c 100644
--- a/vala/valascanner.vala
+++ b/vala/valascanner.vala
@@ -18,6 +18,7 @@
*
* Author:
* Jürg Billeter <j bitron ch>
+ * Jukka-Pekka Iivonen <jp0409 jippii fi>
*/
using GLib;
@@ -28,6 +29,7 @@ using GLib;
public class Vala.Scanner {
public SourceFile source_file { get; private set; }
+ TokenType previous;
char* current;
char* end;
@@ -51,7 +53,8 @@ public class Vala.Scanner {
BRACE,
BRACKET,
TEMPLATE,
- TEMPLATE_PART
+ TEMPLATE_PART,
+ REGEX_LITERAL
}
public Scanner (SourceFile source_file) {
@@ -83,10 +86,178 @@ public class Vala.Scanner {
return (state_stack.length > 0 && state_stack[state_stack.length - 1] == State.TEMPLATE_PART);
}
+ bool in_regex_literal () {
+ return (state_stack.length > 0 && state_stack[state_stack.length - 1] == State.REGEX_LITERAL);
+ }
+
bool is_ident_char (char c) {
return (c.isalnum () || c == '_');
}
+ public TokenType read_regex_token (out SourceLocation token_begin, out SourceLocation token_end) {
+ TokenType type;
+ char* begin = current;
+ token_begin.pos = begin;
+ token_begin.line = line;
+ token_begin.column = column;
+
+ int token_length_in_chars = -1;
+
+ if (current >= end) {
+ type = TokenType.EOF;
+ } else {
+ switch (current[0]) {
+ case '/':
+ type = TokenType.CLOSE_REGEX_LITERAL;
+ current++;
+ state_stack.length--;
+ var fl_i = false;
+ var fl_s = false;
+ var fl_m = false;
+ var fl_x = false;
+ while (current[0] == 'i' || current[0] == 's' || current[0] == 'm' || current[0] == 'x') {
+ switch (current[0]) {
+ case 'i':
+ if (fl_i) {
+ Report.error (new SourceReference (source_file, line, column + token_length_in_chars, line, column + token_length_in_chars), "modifier 'i' used more than once");
+ }
+ fl_i = true;
+ break;
+ case 's':
+ if (fl_s) {
+ Report.error (new SourceReference (source_file, line, column + token_length_in_chars, line, column + token_length_in_chars), "modifier 's' used more than once");
+ }
+ fl_s = true;
+ break;
+ case 'm':
+ if (fl_m) {
+ Report.error (new SourceReference (source_file, line, column + token_length_in_chars, line, column + token_length_in_chars), "modifier 'm' used more than once");
+ }
+ fl_m = true;
+ break;
+ case 'x':
+ if (fl_x) {
+ Report.error (new SourceReference (source_file, line, column + token_length_in_chars, line, column + token_length_in_chars), "modifier 'x' used more than once");
+ }
+ fl_x = true;
+ break;
+ }
+ current++;
+ token_length_in_chars++;
+ }
+ break;
+ default:
+ type = TokenType.REGEX_LITERAL;
+ token_length_in_chars = 0;
+ while (current < end && current[0] != '/') {
+ if (current[0] == '\\') {
+ current++;
+ token_length_in_chars++;
+ if (current >= end) {
+ break;
+ }
+
+ switch (current[0]) {
+ case '\'':
+ case '"':
+ case '\\':
+ case '/':
+ case '^':
+ case '$':
+ case '.':
+ case '[':
+ case ']':
+ case '{':
+ case '}':
+ case '(':
+ case ')':
+ case '?':
+ case '*':
+ case '+':
+ case '-':
+ case '#':
+ case '&':
+ case '~':
+ case ':':
+ case ';':
+ case '<':
+ case '>':
+ case '|':
+ case '%':
+ case '=':
+ case '@':
+ case '0':
+ case 'b':
+ case 'B':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ case 'a':
+ case 'A':
+ case 'p':
+ case 'P':
+ case 'e':
+ case 'd':
+ case 'D':
+ case 's':
+ case 'S':
+ case 'w':
+ case 'W':
+ case 'G':
+ case 'z':
+ case 'Z':
+ current++;
+ token_length_in_chars++;
+ break;
+ case 'x':
+ // hexadecimal escape character
+ current++;
+ token_length_in_chars++;
+ while (current < end && current[0].isxdigit ()) {
+ current++;
+ token_length_in_chars++;
+ }
+ break;
+ default:
+ Report.error (new SourceReference (source_file, line, column + token_length_in_chars, line, column + token_length_in_chars), "invalid escape sequence");
+ break;
+ }
+ } else if (current[0] == '\n') {
+ break;
+ } else {
+ unichar u = ((string) current).get_char_validated ((long) (end - current));
+ if (u != (unichar) (-1)) {
+ current += u.to_utf8 (null);
+ token_length_in_chars++;
+ } else {
+ current++;
+ Report.error (new SourceReference (source_file, line, column + token_length_in_chars, line, column + token_length_in_chars), "invalid UTF-8 character");
+ }
+ }
+ }
+ if (current >= end || current[0] == '\n') {
+ Report.error (new SourceReference (source_file, line, column + token_length_in_chars, line, column + token_length_in_chars), "syntax error, expected \"");
+ state_stack.length--;
+ return read_token (out token_begin, out token_end);
+ }
+ break;
+ }
+ }
+
+ if (token_length_in_chars < 0) {
+ column += (int) (current - begin);
+ } else {
+ column += token_length_in_chars;
+ }
+
+ token_end.pos = current;
+ token_end.line = line;
+ token_end.column = column - 1;
+
+ return type;
+ }
+
public static TokenType get_identifier_or_keyword (char* begin, int len) {
switch (len) {
case 2:
@@ -585,6 +756,8 @@ public class Vala.Scanner {
token_end.column = column - 1;
return TokenType.COMMA;
+ } else if (in_regex_literal ()) {
+ return read_regex_token (out token_begin, out token_end);
}
space ();
@@ -843,11 +1016,18 @@ public class Vala.Scanner {
}
break;
case '/':
- type = TokenType.DIV;
- current++;
- if (current < end && current[0] == '=') {
- type = TokenType.ASSIGN_DIV;
+ if (previous == TokenType.OPEN_PARENS || previous == TokenType.ASSIGN || previous == TokenType.OP_COALESCING
+ || previous == TokenType.COMMA || previous == TokenType.RETURN || previous == TokenType.OPEN_BRACE) {
+ type = TokenType.OPEN_REGEX_LITERAL;
+ state_stack += State.REGEX_LITERAL;
+ current++;
+ } else {
+ type = TokenType.DIV;
current++;
+ if (current < end && current[0] == '=') {
+ type = TokenType.ASSIGN_DIV;
+ current++;
+ }
}
break;
case '%':
@@ -979,6 +1159,7 @@ public class Vala.Scanner {
token_end.pos = current;
token_end.line = line;
token_end.column = column - 1;
+ previous = type;
return type;
}
diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala
index 818ea7d..54e6ced 100644
--- a/vala/valasemanticanalyzer.vala
+++ b/vala/valasemanticanalyzer.vala
@@ -132,6 +132,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
public DataType void_type = new VoidType ();
public DataType bool_type;
public DataType string_type;
+ public DataType regex_type;
public DataType uchar_type;
public DataType short_type;
public DataType ushort_type;
@@ -176,6 +177,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
bool_type = new BooleanType ((Struct) root_symbol.scope.lookup ("bool"));
string_type = new ObjectType ((Class) root_symbol.scope.lookup ("string"));
+ regex_type = new ObjectType ((Class) root_symbol.scope.lookup ("GLib").scope.lookup ("Regex"));
short_type = new IntegerType ((Struct) root_symbol.scope.lookup ("short"));
ushort_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ushort"));
diff --git a/vala/valatokentype.vala b/vala/valatokentype.vala
index 88b8767..8a24684 100644
--- a/vala/valatokentype.vala
+++ b/vala/valatokentype.vala
@@ -49,6 +49,7 @@ public enum Vala.TokenType {
CLOSE_BRACE,
CLOSE_BRACKET,
CLOSE_PARENS,
+ CLOSE_REGEX_LITERAL,
CLOSE_TEMPLATE,
COLON,
COMMA,
@@ -109,6 +110,7 @@ public enum Vala.TokenType {
OPEN_BRACE,
OPEN_BRACKET,
OPEN_PARENS,
+ OPEN_REGEX_LITERAL,
OPEN_TEMPLATE,
OVERRIDE,
OWNED,
@@ -120,6 +122,7 @@ public enum Vala.TokenType {
PUBLIC,
REAL_LITERAL,
REF,
+ REGEX_LITERAL,
REQUIRES,
RETURN,
SEMICOLON,
@@ -177,6 +180,7 @@ public enum Vala.TokenType {
case CLOSE_BRACE: return "`}'";
case CLOSE_BRACKET: return "`]'";
case CLOSE_PARENS: return "`)'";
+ case CLOSE_REGEX_LITERAL: return "`/'";
case COLON: return "`:'";
case COMMA: return "`,'";
case CONST: return "`const'";
@@ -232,6 +236,7 @@ public enum Vala.TokenType {
case OPEN_BRACE: return "`{'";
case OPEN_BRACKET: return "`['";
case OPEN_PARENS: return "`('";
+ case OPEN_REGEX_LITERAL: return "`/'";
case OVERRIDE: return "`override'";
case OWNED: return "`owned'";
case PARAMS: return "`params'";
@@ -242,6 +247,7 @@ public enum Vala.TokenType {
case PUBLIC: return "`public'";
case REAL_LITERAL: return "real literal";
case REF: return "`ref'";
+ case REGEX_LITERAL: return "regex literal";
case REQUIRES: return "`requires'";
case RETURN: return "`return'";
case SEMICOLON: return "`;'";
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]