diff --git a/.idea/ant.xml b/.idea/ant.xml
index dca320aa923..902b2815260 100644
--- a/.idea/ant.xml
+++ b/.idea/ant.xml
@@ -10,6 +10,14 @@
+
+
+
+
+
+
+
+
diff --git a/grammar/buildGrammarLexer.xml b/grammar/buildGrammarLexer.xml
new file mode 100644
index 00000000000..ecf2cfdc4ce
--- /dev/null
+++ b/grammar/buildGrammarLexer.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/grammar/grammar.iml b/grammar/grammar.iml
index d5c07432750..5959571cff2 100644
--- a/grammar/grammar.iml
+++ b/grammar/grammar.iml
@@ -7,6 +7,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/grammar/src/attributes.grm b/grammar/src/attributes.grm
index 1a0d6a9e89c..1606c15138c 100644
--- a/grammar/src/attributes.grm
+++ b/grammar/src/attributes.grm
@@ -1,3 +1,7 @@
+/**
+h2. Annotations
+*/
+
attributes
: attributeAnnotation*
;
diff --git a/grammar/src/class.grm b/grammar/src/class.grm
index d30f6da5118..41fb9449dab 100644
--- a/grammar/src/class.grm
+++ b/grammar/src/class.grm
@@ -1,3 +1,7 @@
+/**
+h2. Classes
+*/
+
/*
internal class Example>(protected val x : Foo, y : Some)
diff --git a/grammar/src/class_members.grm b/grammar/src/class_members.grm
index 2a355ca1ccc..4394722d5c5 100644
--- a/grammar/src/class_members.grm
+++ b/grammar/src/class_members.grm
@@ -1,3 +1,7 @@
+/**
+h3. Class members
+*/
+
/*
class Example(a : Foo, i : Int) : Bar(i), Some {
// constrtuctors:
@@ -37,20 +41,24 @@ memberDeclaration
: function
: property
: class
- : extension
+ : extension ยง
: typedef
: anonymousInitializer
;
+anonymousInitializer
+ : block
+ ;
+
classObject
: modifiers "class" object
;
constructor
- : modifiers "this" functionParameters (":" initializer{","}) block?
+ : modifiers "this" valueParameters (":" initializer{","}) block?
;
-functionParameters
+valueParameters
: "(" functionParameter{","}? ")" // default values
;
@@ -71,7 +79,7 @@ function
: modifiers "fun" typeParameters?
(type "." | attributes/*for receiver type*/)?
SimpleName
- typeParameters? functionParameters (":" type)?
+ typeParameters? valueParameters (":" type)?
functionBody?
;
diff --git a/grammar/src/control.grm b/grammar/src/control.grm
index bbcd4f95e04..80c60a23670 100644
--- a/grammar/src/control.grm
+++ b/grammar/src/control.grm
@@ -1,3 +1,7 @@
+/**
+h3. Control structures
+*/
+
if
: "if" "(" expression ")" expression SEMI? ("else" expression)?
;
@@ -21,7 +25,7 @@ loop
;
for
- : "for" "(" attributes valOrVar? SimpleName (":" type)? "in" expression ")" expression
+ : "for" "(" attributes ("val" | "var")? SimpleName (":" type)? "in" expression ")" expression
;
while
diff --git a/grammar/src/enum.grm b/grammar/src/enum.grm
index 422710ae2b2..db02632fffb 100644
--- a/grammar/src/enum.grm
+++ b/grammar/src/enum.grm
@@ -1,7 +1,11 @@
+/**
+h3. Enum classes
+*/
+
enumClassBody
: "{" enumEntry* "}"
;
enumEntry
- : modifiers SimpleName typeParameters? primaryConstructorParameters? (":" initializer{","})? classBody?
+ : modifiers SimpleName typeParameters? valueParameters? (":" initializer{","})? classBody?
;
diff --git a/grammar/src/expressions.grm b/grammar/src/expressions.grm
index edceb3ebf36..ac8b3af29c7 100644
--- a/grammar/src/expressions.grm
+++ b/grammar/src/expressions.grm
@@ -1,3 +1,7 @@
+/**
+h2. Expressions
+*/
+
/*
Decreasing precedence:
memberAccessOperation
@@ -108,7 +112,7 @@ literalConstant
: StringWithTemplates
: NoEscapeString
: IntegerLiteral
- : LongLiteral
+ : HexadecimalLiteral
: CharacterLiteral
: FloatLiteral
: "null"
@@ -148,7 +152,7 @@ typeOperation
: "as" : "as?" : ":"
;
-isOPeration
+isOperation
: "is" : "!is"
;
@@ -210,17 +214,14 @@ jump
// yield ?
;
-stringLiteral
- : StringWithTemplates
- : NoEscapeString
- ;
-
-tupleLiteral // Ambiguity when after a SimpleName (infix call). In this case (e) is treated as an expression in parentheses
- // to put a tuple, write write ((e))
+// Ambiguity when after a SimpleName (infix call). In this case (e) is treated as an expression in parentheses
+// to put a tuple, write write ((e))
+tupleLiteral
: "(" ((SimpleName "=")? expression){","} ")"
;
-functionLiteral // one can use "it" as a parameter name
+// one can use "it" as a parameter name
+functionLiteral
: "{" statements "}"
: "{" (type ".")? modifiers SimpleName "=>" statements "}"
: "{" (type ".")? "(" (modifiers SimpleName (":" type)?){","} ")" (":" type)? "=>" statements "}"
diff --git a/grammar/src/lexical.grm b/grammar/src/lexical.grm
index e6144a1b2cb..759a43b786e 100644
--- a/grammar/src/lexical.grm
+++ b/grammar/src/lexical.grm
@@ -1,15 +1,42 @@
-SimpleName : /*java identifier*/;
-FieldName : "$" SimpleName;
-LabelName : "@" SimpleName;
-[helper] Digit : ["0".."9"];
-IntegerLiteral : Digit+ "L"?
-[helper] HexDigit : Digit | ["A"-"F", "a"-"f"];
-HexadecimalLiteral : "0x" HexDigit+;
+/**
+h1. Lexical structure
+*/
-CharacterLiteral : /*character as in Java*/;
+SimpleName
+ : ;
+FieldName
+ : "$" SimpleName;
+LabelName
+ : "@" SimpleName;
-StringWithTemplates : /*single-quoted string, $ can be escaped*/;
-NoEscapeString : /* """-quoted string */;
+[helper]
+Digit
+ : ["0".."9"];
+
+IntegerLiteral
+ : Digit+ "L"?
+
+FloatLiteral
+ : ;
+
+[helper]
+HexDigit
+ : Digit | ["A"-"F", "a"-"f"];
+
+HexadecimalLiteral
+ : "0x" HexDigit+;
+
+CharacterLiteral
+ : ;
+
+StringWithTemplates
+ : ;
+
+NoEscapeString
+ : <"""-quoted string>;
+
+SEMI
+ : ;
/* Symbols:
diff --git a/grammar/src/modifiers.grm b/grammar/src/modifiers.grm
index 160f994233f..757dd3a47c4 100644
--- a/grammar/src/modifiers.grm
+++ b/grammar/src/modifiers.grm
@@ -1,3 +1,7 @@
+/**
+h3. Modifiers
+*/
+
modifiers
: modifier*
;
diff --git a/grammar/src/notation.grm b/grammar/src/notation.grm
new file mode 100644
index 00000000000..cab214bd145
--- /dev/null
+++ b/grammar/src/notation.grm
@@ -0,0 +1,21 @@
+/**
+h1. Notation
+
+This section informally explains the grammar notation used below.
+
+h2. Symbols and naming
+
+_Terminal symbol_ names start with an uppercase letter, e.g. *SimpleName*
+_Nonterminal symbol_ names start with lowercase letter, e.g. *jetFile*
+Each _production_ starts with a colon (*:*)
+_Symbol definitions_ may have many productions and are terminated by a semicolon (*;*)
+Symbol definitions may be prepended with _attributes_, e.g. {{start}} attribute denotes a start symbol
+
+h2. EBNF expressions
+
+Operator {color:blue}*|*{color} denotes _alternative_
+Operator {color:blue}*\**{color} denotes _iteration_ (zero or more)
+Operator {color:blue}*+*{color} denotes _iteration_ (one or one)
+Operator {color:blue}*?*{color} denotes _option_ (zero or one)
+alpha{color:blue}*{*{color}beta{color:blue}*}*{color} denotes a nonempty _beta_-separated list of _alpha_s
+*/
diff --git a/grammar/src/org/jetbrains/jet/grammar/Annotation.java b/grammar/src/org/jetbrains/jet/grammar/Annotation.java
new file mode 100644
index 00000000000..aa8f6e7ddea
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/Annotation.java
@@ -0,0 +1,15 @@
+package org.jetbrains.jet.grammar;
+
+/**
+ * @author abreslav
+ */
+public class Annotation extends Token {
+ public Annotation(CharSequence text) {
+ super(text);
+ }
+
+ @Override
+ public String toString() {
+ return "{{" + super.toString().replaceAll("\\[", "").replaceAll("\\]", "") + "}}";
+ }
+}
diff --git a/grammar/src/org/jetbrains/jet/grammar/Comment.java b/grammar/src/org/jetbrains/jet/grammar/Comment.java
new file mode 100644
index 00000000000..957ba49fea7
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/Comment.java
@@ -0,0 +1,15 @@
+package org.jetbrains.jet.grammar;
+
+/**
+ * @author abreslav
+ */
+public class Comment extends Token {
+ public Comment(CharSequence text) {
+ super(text);
+ }
+
+ @Override
+ public String toString() {
+ return "";//getText().toString().replaceAll("\\{", "\\\\{").replaceAll("\\[", "\\\\[").replaceAll("\\(", "\\\\(");
+ }
+}
diff --git a/grammar/src/org/jetbrains/jet/grammar/ConfluenceHyperlinksGenerator.java b/grammar/src/org/jetbrains/jet/grammar/ConfluenceHyperlinksGenerator.java
new file mode 100644
index 00000000000..e5493bed4d7
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/ConfluenceHyperlinksGenerator.java
@@ -0,0 +1,150 @@
+package org.jetbrains.jet.grammar;
+
+import java.awt.*;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.ClipboardOwner;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.*;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author abreslav
+ */
+public class ConfluenceHyperlinksGenerator {
+
+ public static void main(String[] args) throws IOException {
+ String grammarExtension = "grm";
+ File grammarDir = new File("grammar/src");
+
+ List fileNamesInOrder = Arrays.asList(
+ "notation",
+ "lexical",
+ "toplevel",
+ "class",
+ "class_members",
+ "enum",
+ "types",
+ "modifiers",
+ "attributes",
+ "control",
+ "expressions",
+ "when"
+ );
+
+ StringBuilder allRules = new StringBuilder();
+ Set used = new HashSet();
+ for (String fileName : fileNamesInOrder) {
+ File file = new File(grammarDir, fileName + "." + grammarExtension);
+ used.add(file);
+ FileReader fileReader = new FileReader(file);
+ try {
+ int c;
+ while ((c = fileReader.read()) != -1) {
+ allRules.append((char) c);
+ }
+ allRules.append("\n");
+ allRules.append("\n");
+ } finally {
+ fileReader.close();
+ }
+ }
+
+ for (File file : grammarDir.listFiles()) {
+ if (file.getName().endsWith(grammarExtension)) {
+ if (!used.contains(file)) {
+ throw new IllegalStateException("Unused grammar file : " + file.getAbsolutePath());
+ }
+ }
+ }
+
+ StringBuilder output = new StringBuilder();
+
+ Pattern symbolReference = Pattern.compile("^\\w+$", Pattern.MULTILINE);
+ Matcher matcher = symbolReference.matcher(allRules);
+ int copiedUntil = 0;
+ while (matcher.find()) {
+ int start = matcher.start();
+ output.append(allRules.subSequence(copiedUntil, start));
+
+ String group = matcher.group();
+ output.append("&").append(group);
+ copiedUntil = matcher.end();
+ }
+ output.append(allRules.subSequence(copiedUntil, allRules.length()));
+// System.out.println(output);
+
+ _GrammarLexer grammarLexer = new _GrammarLexer((Reader) null);
+ grammarLexer
+ .reset(output, 0, output.length(), 0);
+
+ StringBuilder result = new StringBuilder("h1. Contents\n").append("{toc:style=disc|indent=20px}");
+
+ Set declaredSymbols = new HashSet();
+ Set usedSymbols = new HashSet();
+ List tokens = new ArrayList();
+
+ while (true) {
+ Token advance = grammarLexer.advance();
+ if (advance == null) {
+ break;
+ }
+ if (advance instanceof Declaration) {
+ Declaration declaration = (Declaration) advance;
+ declaredSymbols.add(declaration.getName());
+ }
+ else if (advance instanceof Identifier) {
+ Identifier identifier = (Identifier) advance;
+ usedSymbols.add(identifier.getName());
+ }
+ tokens.add(advance);
+ }
+
+ for (Token token : tokens) {
+ if (token instanceof Declaration) {
+ Declaration declaration = (Declaration) token;
+ if (!usedSymbols.contains(declaration.getName())) {
+ result.append("(!) *Unused!* ");
+ System.out.println("Unused: " + token);
+ }
+ }
+ else if (token instanceof Identifier) {
+ Identifier identifier = (Identifier) token;
+ if (!declaredSymbols.contains(identifier.getName())) {
+ result.append("(!) *Undeclared!* ");
+ System.out.println("Undeclared: " + token);
+ }
+ }
+ result.append(token);
+ }
+
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ clipboard.setContents(new StringSelection(result.toString()), new ClipboardOwner() {
+ @Override
+ public void lostOwnership(Clipboard clipboard, Transferable contents) {
+
+ }
+ });
+ }
+
+ private static Set recordStarts(StringBuilder allRules, String regex) {
+ Pattern symbolDeclaration = Pattern.compile(regex, Pattern.MULTILINE);
+ Matcher matcher = symbolDeclaration.matcher(allRules);
+ Set declarationStarts = new HashSet();
+ while (matcher.find()) {
+ if (matcher.groupCount() > 0) {
+ declarationStarts.add(matcher.start(1));
+ }
+ else {
+ declarationStarts.add(matcher.start());
+ }
+ }
+ return declarationStarts;
+ }
+}
diff --git a/grammar/src/org/jetbrains/jet/grammar/Declaration.java b/grammar/src/org/jetbrains/jet/grammar/Declaration.java
new file mode 100644
index 00000000000..47451807c88
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/Declaration.java
@@ -0,0 +1,22 @@
+package org.jetbrains.jet.grammar;
+
+/**
+ * @author abreslav
+ */
+public class Declaration extends Token {
+ private final String name;
+
+ public Declaration(CharSequence text) {
+ super(text);
+ name = text.toString().substring(1);
+ }
+
+ @Override
+ public String toString() {
+ return "{anchor:" + name + "}*" + name + "*";
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/grammar/src/org/jetbrains/jet/grammar/DocComment.java b/grammar/src/org/jetbrains/jet/grammar/DocComment.java
new file mode 100644
index 00000000000..2c78536ef7b
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/DocComment.java
@@ -0,0 +1,16 @@
+package org.jetbrains.jet.grammar;
+
+/**
+ * @author abreslav
+ */
+public class DocComment extends Token {
+ public DocComment(CharSequence text) {
+ super(text);
+ }
+
+ @Override
+ public String toString() {
+ String s = super.toString();
+ return s.substring(3, s.length() - 2);
+ }
+}
diff --git a/grammar/src/org/jetbrains/jet/grammar/Grammar.flex b/grammar/src/org/jetbrains/jet/grammar/Grammar.flex
new file mode 100644
index 00000000000..9dc151b8b70
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/Grammar.flex
@@ -0,0 +1,102 @@
+/* It's an automatically generated code. Do not modify it. */
+package org.jetbrains.jet.grammar;
+
+//import com.intellij.lexer.*;
+//import com.intellij.psi.*;
+//import com.intellij.psi.tree.IElementType;
+
+//import org.jetbrains.jet.lexer.JetTokens;
+
+%%
+
+%unicode
+%class _GrammarLexer
+%function advance
+%type Token
+%eof{ return;
+%eof}
+
+DIGIT=[0-9]
+HEX_DIGIT=[0-9A-Fa-f]
+WHITE_SPACE_CHAR=[\ \n\t\f]
+
+// TODO: prohibit '$' in identifiers?
+PLAIN_IDENTIFIER=[:jletter:] [:jletterdigit:]*
+// TODO: this one MUST allow everything accepted by the runtime
+// TODO: Replace backticks by one backslash in the begining
+ESCAPED_IDENTIFIER = `{PLAIN_IDENTIFIER}`
+IDENTIFIER = {PLAIN_IDENTIFIER}|{ESCAPED_IDENTIFIER}
+DECLARATION_IDENTIFIER = "&" {PLAIN_IDENTIFIER}
+FIELD_IDENTIFIER = \${IDENTIFIER}
+LABEL_IDENTIFIER = \@{IDENTIFIER}
+
+BLOCK_COMMENT=("/*"[^"*"]{COMMENT_TAIL})|"/*"
+// TODO: Wiki markup for doc comments?
+DOC_COMMENT="/*""*"+("/"|([^"/""*"]{COMMENT_TAIL}))?
+COMMENT_TAIL=([^"*"]*("*"+[^"*""/"])?)*("*"+"/")?
+EOL_COMMENT="/""/"[^\n]*
+
+INTEGER_LITERAL={DECIMAL_INTEGER_LITERAL}|{HEX_INTEGER_LITERAL}|{BIN_INTEGER_LITERAL}
+DECIMAL_INTEGER_LITERAL=(0|([1-9]({DIGIT})*))
+HEX_INTEGER_LITERAL=0[Xx]({HEX_DIGIT})*
+BIN_INTEGER_LITERAL=0[Bb]({DIGIT})*
+LONG_LITERAL=({INTEGER_LITERAL})[Ll]
+
+//FLOAT_LITERAL=(({FLOATING_POINT_LITERAL1})[Ff])|(({FLOATING_POINT_LITERAL2})[Ff])|(({FLOATING_POINT_LITERAL3})[Ff])|(({FLOATING_POINT_LITERAL4})[Ff])
+//DOUBLE_LITERAL=(({FLOATING_POINT_LITERAL1})[Dd]?)|(({FLOATING_POINT_LITERAL2})[Dd]?)|(({FLOATING_POINT_LITERAL3})[Dd]?)|(({FLOATING_POINT_LITERAL4})[Dd])
+DOUBLE_LITERAL={FLOATING_POINT_LITERAL1}|{FLOATING_POINT_LITERAL2}|{FLOATING_POINT_LITERAL3}|{FLOATING_POINT_LITERAL4}
+FLOATING_POINT_LITERAL1=({DIGIT})+"."({DIGIT})+({EXPONENT_PART})?
+FLOATING_POINT_LITERAL2="."({DIGIT})+({EXPONENT_PART})?
+FLOATING_POINT_LITERAL3=({DIGIT})+({EXPONENT_PART})
+FLOATING_POINT_LITERAL4=({DIGIT})+
+EXPONENT_PART=[Ee]["+""-"]?({DIGIT})*
+HEX_FLOAT_LITERAL={HEX_SIGNIFICAND}{BINARY_EXPONENT}[Ff]
+//HEX_DOUBLE_LITERAL={HEX_SIGNIFICAND}{BINARY_EXPONENT}[Dd]?
+HEX_DOUBLE_LITERAL={HEX_SIGNIFICAND}{BINARY_EXPONENT}?
+BINARY_EXPONENT=[Pp][+-]?{DIGIT}+
+HEX_SIGNIFICAND={HEX_INTEGER_LITERAL}|0[Xx]{HEX_DIGIT}*\.{HEX_DIGIT}+
+//HEX_SIGNIFICAND={HEX_INTEGER_LITERAL}|{HEX_INTEGER_LITERAL}\.|0[Xx]{HEX_DIGIT}*\.{HEX_DIGIT}+
+
+CHARACTER_LITERAL="'"([^\\\'\n]|{ESCAPE_SEQUENCE})*("'"|\\)?
+// TODO: introduce symbols (e.g. 'foo) as another way to write string literals
+STRING_LITERAL=\"([^\\\"\n]|{ESCAPE_SEQUENCE})*(\"|\\)?
+ANGLE_STRING_LITERAL=\<([^\\\>\n])*(\>|\\)?
+ESCAPE_SEQUENCE=\\[^\n]
+
+// ANY_ESCAPE_SEQUENCE = \\[^]
+THREE_QUO = (\"\"\")
+ONE_TWO_QUO = (\"[^\"]) | (\"\"[^\"])
+QUO_STRING_CHAR = [^\"] | {ONE_TWO_QUO}
+RAW_STRING_LITERAL = {THREE_QUO} {QUO_STRING_CHAR}* {THREE_QUO}?
+
+%%
+
+ {BLOCK_COMMENT} { return new Comment(yytext()); }
+ {DOC_COMMENT} { return new DocComment(yytext()); }
+
+ ({WHITE_SPACE_CHAR})+ { return new WhiteSpace(yytext()); }
+
+ {EOL_COMMENT} { return new Comment(yytext()); }
+
+ {STRING_LITERAL} { return new StringToken(yytext()); }
+ {ANGLE_STRING_LITERAL} { return new StringToken(yytext()); }
+ {IDENTIFIER} { return new Identifier(yytext()); }
+ "[" {IDENTIFIER} "]" { return new Annotation(yytext()); }
+ {DECLARATION_IDENTIFIER} { return new Declaration(yytext()); }
+
+ ":" { return new SymbolToken(yytext()); }
+ "{" { return new SymbolToken("\\" + yytext()); }
+ "}" { return new SymbolToken("\\" + yytext()); }
+ "[" { return new SymbolToken("\\" + yytext()); }
+ "]" { return new SymbolToken("\\" + yytext()); }
+ "(" { return new SymbolToken("\\" + yytext()); }
+ ")" { return new SymbolToken("\\" + yytext()); }
+ "*" { return new SymbolToken(yytext()); }
+ "+" { return new SymbolToken(yytext()); }
+ "?" { return new SymbolToken(yytext()); }
+ "|" { return new SymbolToken(yytext()); }
+ "-" { return new SymbolToken(yytext()); }
+ "." { return new SymbolToken(yytext()); }
+
+ . { return new Other(yytext()); }
+
diff --git a/grammar/src/org/jetbrains/jet/grammar/Identifier.java b/grammar/src/org/jetbrains/jet/grammar/Identifier.java
new file mode 100644
index 00000000000..057c90400c5
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/Identifier.java
@@ -0,0 +1,22 @@
+package org.jetbrains.jet.grammar;
+
+/**
+ * @author abreslav
+ */
+public class Identifier extends Token {
+ private final String name;
+
+ public Identifier(CharSequence text) {
+ super(text);
+ name = text.toString();
+ }
+
+ @Override
+ public String toString() {
+ return "[#" + getText() + "]";
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/grammar/src/org/jetbrains/jet/grammar/Other.java b/grammar/src/org/jetbrains/jet/grammar/Other.java
new file mode 100644
index 00000000000..e4af84e3d7d
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/Other.java
@@ -0,0 +1,10 @@
+package org.jetbrains.jet.grammar;
+
+/**
+ * @author abreslav
+ */
+public class Other extends Token {
+ public Other(CharSequence text) {
+ super(text);
+ }
+}
diff --git a/grammar/src/org/jetbrains/jet/grammar/StringToken.java b/grammar/src/org/jetbrains/jet/grammar/StringToken.java
new file mode 100644
index 00000000000..d618a6c78c9
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/StringToken.java
@@ -0,0 +1,15 @@
+package org.jetbrains.jet.grammar;
+
+/**
+ * @author abreslav
+ */
+public class StringToken extends Token {
+ public StringToken(CharSequence text) {
+ super(text);
+ }
+
+ @Override
+ public String toString() {
+ return "{color:green}*{{" + getText().toString().replaceAll("\\{", "\\\\{").replaceAll("\\[", "\\\\[").replaceAll("!", "\\\\!") + "}}*{color}";
+ }
+}
diff --git a/grammar/src/org/jetbrains/jet/grammar/SymbolToken.java b/grammar/src/org/jetbrains/jet/grammar/SymbolToken.java
new file mode 100644
index 00000000000..93576bc8f89
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/SymbolToken.java
@@ -0,0 +1,15 @@
+package org.jetbrains.jet.grammar;
+
+/**
+ * @author abreslav
+ */
+public class SymbolToken extends Token {
+ public SymbolToken(CharSequence text) {
+ super(text);
+ }
+
+ @Override
+ public String toString() {
+ return "{color:blue}*" + getText().toString().replaceAll("\\*", "\\\\*") + "*{color}";
+ }
+}
diff --git a/grammar/src/org/jetbrains/jet/grammar/Token.java b/grammar/src/org/jetbrains/jet/grammar/Token.java
new file mode 100644
index 00000000000..32a9997013e
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/Token.java
@@ -0,0 +1,22 @@
+package org.jetbrains.jet.grammar;
+
+/**
+ * @author abreslav
+ */
+public class Token {
+ private final CharSequence text;
+
+ public Token(CharSequence text) {
+ this.text = text;
+ }
+
+ public CharSequence getText() {
+ return text;
+ }
+
+
+ @Override
+ public String toString() {
+ return getText().toString();
+ }
+}
diff --git a/grammar/src/org/jetbrains/jet/grammar/WhiteSpace.java b/grammar/src/org/jetbrains/jet/grammar/WhiteSpace.java
new file mode 100644
index 00000000000..fdf5a3268d6
--- /dev/null
+++ b/grammar/src/org/jetbrains/jet/grammar/WhiteSpace.java
@@ -0,0 +1,15 @@
+package org.jetbrains.jet.grammar;
+
+/**
+ * @author abreslav
+ */
+public class WhiteSpace extends Token {
+ public WhiteSpace(CharSequence text) {
+ super(text);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString().replaceAll(" ", " ");
+ }
+}
diff --git a/grammar/src/toplevel.grm b/grammar/src/toplevel.grm
index 6e87ff352cb..2f2456f6ad7 100644
--- a/grammar/src/toplevel.grm
+++ b/grammar/src/toplevel.grm
@@ -1,8 +1,15 @@
-[start] jetlFile
+/**
+h1. Syntax
+*/
+
+
+[start]
+jetFile
: preamble toplevelObject*
;
-[start] script
+[start]
+script
: preamble expression*
;
diff --git a/grammar/src/types.grm b/grammar/src/types.grm
index 290125415ac..e2cf43dbcaf 100644
--- a/grammar/src/types.grm
+++ b/grammar/src/types.grm
@@ -1,3 +1,7 @@
+/**
+h2. Types
+*/
+
/*
Foo, T, Object> // user type
diff --git a/grammar/src/when.grm b/grammar/src/when.grm
index 9256fbe612b..d817cb8ad52 100644
--- a/grammar/src/when.grm
+++ b/grammar/src/when.grm
@@ -1,3 +1,7 @@
+/**
+h3. Pattern matching
+*/
+
when
: "when" "(" (modifiers "val" SimpleName "=")? expression ")" "{"
whenEntry*
@@ -35,7 +39,7 @@ pattern
decomposerPattern
: type
// TODO : typeParameters will be consumed by the expression
- : elvisExpression typeParameters? '@' tuplePattern
+ : elvisExpression typeParameters? "@" tuplePattern
;
constantPattern