view graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg @ 18962:cfb85e1f4ca5

Prevent polluting SLFunctionRegistry (via SLNodeFactory.createRead()) with LHS names of assignment
author Paul Woegerer <paul.woegerer@oracle.com>
date Tue, 27 Jan 2015 14:24:59 +0100
parents dc2e000bed40
children
line wrap: on
line source

/*
 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * This is the grammar of SL that is used to automatically generate the Parser.java and Scanner.java
 * files. You can download the parser generator Coco/R from http://ssw.jku.at/coco/. Then run
 * "java -jar Coco.jar SimpleLanguage.atg"
 */

COMPILER SimpleLanguage

CHARACTERS

letter = 'A'..'Z' + 'a'..'z'.
nonZeroDigit = "123456789".
digit = "0123456789".
cr = '\r'.
lf = '\n'.
tab = '\t'.
stringChar = ANY - "\"" - '\\' - cr - lf.

TOKENS

identifier = letter {letter | digit}.
stringLiteral = "\"" { stringChar } "\"".
numericLiteral = "0" | nonZeroDigit { digit }.

PRAGMAS

COMMENTS FROM "/*" TO "*/"
COMMENTS FROM "//" TO lf
IGNORE cr + lf + tab

PRODUCTIONS


SimpleLanguage
=
Function
{
     Function
}
.


Function
=
"function"
identifier                                      (. Token identifierToken = t; .)
"("                                             (. int bodyStartPos = t.charPos; .)
                                                (. factory.startFunction(identifierToken, bodyStartPos); .)
[
    identifier                                  (. factory.addFormalParameter(t); .)
    {
        ","
        identifier                              (. factory.addFormalParameter(t); .)
    }
]
")"
Block<out SLStatementNode body, false>          (. factory.finishFunction(body); .)
.



Block<out SLStatementNode result, boolean inLoop>
=                                               (. factory.startBlock();
                                                   List<SLStatementNode> body = new ArrayList<>(); .)
"{"                                             (. int start = t.charPos; .)
{
    Statement<out SLStatementNode s, inLoop>    (. body.add(s); .)
}
"}"                                             (. int length = (t.charPos + t.val.length()) - start; .)
                                                (. result = factory.finishBlock(body, start, length); .)
.


Statement<out SLStatementNode result, boolean inLoop>
=                                               (. result = null; .)
(
    WhileStatement<out result>
|
    "break"                                     (. if (inLoop) { result = factory.createBreak(t); } else { SemErr("break used outside of loop"); } .)
    ";"
|
    "continue"                                  (. if (inLoop) { result = factory.createContinue(t); } else { SemErr("continue used outside of loop"); } .)
    ";"
|
    IfStatement<out result, inLoop>
|
    ReturnStatement<out result>
|
    Expression<out result> ";"
)
.


WhileStatement<out SLStatementNode result>
=
"while"                                         (. Token whileToken = t; .)
"("
Expression<out SLExpressionNode condition>
")"
Block<out SLStatementNode body, true>           (. result = factory.createWhile(whileToken, condition, body); .)
.


IfStatement<out SLStatementNode result, boolean inLoop>
=
"if"                                            (. Token ifToken = t; .)
"("
Expression<out SLExpressionNode condition>
")"
Block<out SLStatementNode thenPart, inLoop>     (. SLStatementNode elsePart = null; .)
[
    "else"
    Block<out elsePart, inLoop>
]                                               (. result = factory.createIf(ifToken, condition, thenPart, elsePart); .)
.


ReturnStatement<out SLStatementNode result>
=
"return"                                        (. Token returnToken = t;
                                                   SLExpressionNode value = null; .)
[
    Expression<out value>
]                                               (. result = factory.createReturn(returnToken, value); .)
";"
.


Expression<out SLExpressionNode result>
=
LogicTerm<out result>
{
    "||"                                        (. Token op = t; .)
    LogicTerm<out SLExpressionNode right>       (. result = factory.createBinary(op, result, right); .)
}
.


LogicTerm<out SLExpressionNode result>
=
LogicFactor<out result>
{
    "&&"                                        (. Token op = t; .)
    LogicFactor<out SLExpressionNode right>     (. result = factory.createBinary(op, result, right); .)
}
.


LogicFactor<out SLExpressionNode result>
=
Arithmetic<out result>
[
    ("<" | "<=" | ">" | ">=" | "==" | "!=" )    (. Token op = t; .)
    Arithmetic<out SLExpressionNode right>      (.  result = factory.createBinary(op, result, right); .)
]
.


Arithmetic<out SLExpressionNode result>
=
Term<out result>
{
    ("+" | "-")                                 (. Token op = t; .)
    Term<out SLExpressionNode right>            (. result = factory.createBinary(op, result, right); .)
}
.


Term<out SLExpressionNode result>
=
Factor<out result>
{
    ("*" | "/")                                 (. Token op = t; .)
    Factor<out SLExpressionNode right>          (. result = factory.createBinary(op, result, right); .)
}
.


Factor<out SLExpressionNode result>
=                                               (. result = null; .)
(
    identifier
    (
        MemberExpression<out result, null, null, t>
    |
                                                (. result = factory.createRead(t); .)
    )
|
    stringLiteral                               (. result = factory.createStringLiteral(t); .)
|
    numericLiteral                              (. result = factory.createNumericLiteral(t); .)
|
    "("                                         (. int start = t.charPos; .)
    Expression<out result>                      (. SLExpressionNode expr = result; .)
    ")"                                         (. int length = (t.charPos + t.val.length()) - start; .)
                                                (. result = factory.createParenExpression(expr, start, length); .)
)
.


MemberExpression<out SLExpressionNode result, SLExpressionNode r, SLExpressionNode assignmentReceiver, Token assignmentName>
=                                               (. result = null;
                                                   SLExpressionNode receiver = r;
                                                   Token nestedAssignmentName = null; .)
(
    "("                                         (. List<SLExpressionNode> parameters = new ArrayList<>();
                                                   SLExpressionNode parameter;
                                                   if (receiver == null) {
                                                       receiver = factory.createRead(assignmentName); 
                                                   } .)
    [
        Expression<out parameter>               (. parameters.add(parameter); .)
        {
            ","
            Expression<out parameter>           (. parameters.add(parameter); .)
        }
    ]
    ")"                                         (. Token finalToken = t; .)
                                                (. result = factory.createCall(receiver, parameters, finalToken); .)
|
    "="
    Expression<out SLExpressionNode value>      (. if (assignmentName == null) {
                                                       SemErr("invalid assignment target");
                                                   } else if (assignmentReceiver == null) {
                                                       result = factory.createAssignment(assignmentName, value);
                                                   } else {
                                                       result = factory.createWriteProperty(assignmentReceiver, assignmentName, value);
                                                   } .)
|
    "."                                         (. if (receiver == null) {
                                                       receiver = factory.createRead(assignmentName); 
                                                   } .)
    identifier
                                                (. result = factory.createReadProperty(receiver, t); .)
                                                (. nestedAssignmentName = t; .)
)
[
    MemberExpression<out result, result, receiver, nestedAssignmentName>
]
.


END SimpleLanguage.