From c65d59c1c1d175e1b81f440d8c893b91ae7f7f43 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 28 Jun 2011 19:12:26 +0400 Subject: [PATCH] Rendering the grammar for Confluence --- .idea/ant.xml | 8 + grammar/buildGrammarLexer.xml | 43 +++++ grammar/grammar.iml | 9 ++ grammar/src/attributes.grm | 4 + grammar/src/class.grm | 4 + grammar/src/class_members.grm | 16 +- grammar/src/control.grm | 6 +- grammar/src/enum.grm | 6 +- grammar/src/expressions.grm | 21 +-- grammar/src/lexical.grm | 47 ++++-- grammar/src/modifiers.grm | 4 + grammar/src/notation.grm | 21 +++ .../org/jetbrains/jet/grammar/Annotation.java | 15 ++ .../org/jetbrains/jet/grammar/Comment.java | 15 ++ .../ConfluenceHyperlinksGenerator.java | 150 ++++++++++++++++++ .../jetbrains/jet/grammar/Declaration.java | 22 +++ .../org/jetbrains/jet/grammar/DocComment.java | 16 ++ .../org/jetbrains/jet/grammar/Grammar.flex | 102 ++++++++++++ .../org/jetbrains/jet/grammar/Identifier.java | 22 +++ .../src/org/jetbrains/jet/grammar/Other.java | 10 ++ .../jetbrains/jet/grammar/StringToken.java | 15 ++ .../jetbrains/jet/grammar/SymbolToken.java | 15 ++ .../src/org/jetbrains/jet/grammar/Token.java | 22 +++ .../org/jetbrains/jet/grammar/WhiteSpace.java | 15 ++ grammar/src/toplevel.grm | 11 +- grammar/src/types.grm | 4 + grammar/src/when.grm | 6 +- 27 files changed, 600 insertions(+), 29 deletions(-) create mode 100644 grammar/buildGrammarLexer.xml create mode 100644 grammar/src/notation.grm create mode 100644 grammar/src/org/jetbrains/jet/grammar/Annotation.java create mode 100644 grammar/src/org/jetbrains/jet/grammar/Comment.java create mode 100644 grammar/src/org/jetbrains/jet/grammar/ConfluenceHyperlinksGenerator.java create mode 100644 grammar/src/org/jetbrains/jet/grammar/Declaration.java create mode 100644 grammar/src/org/jetbrains/jet/grammar/DocComment.java create mode 100644 grammar/src/org/jetbrains/jet/grammar/Grammar.flex create mode 100644 grammar/src/org/jetbrains/jet/grammar/Identifier.java create mode 100644 grammar/src/org/jetbrains/jet/grammar/Other.java create mode 100644 grammar/src/org/jetbrains/jet/grammar/StringToken.java create mode 100644 grammar/src/org/jetbrains/jet/grammar/SymbolToken.java create mode 100644 grammar/src/org/jetbrains/jet/grammar/Token.java create mode 100644 grammar/src/org/jetbrains/jet/grammar/WhiteSpace.java 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