📄 ocl.g
字号:
/* * USE - UML based specification environment * Copyright (C) 1999-2004 Mark Richters, University of Bremen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* $ProjectHeader: use 2-3-0-release.1 Mon, 12 Sep 2005 20:18:33 +0200 green $ */// set package for all generated classesheader { /* * USE - UML based specification environment * Copyright (C) 1999-2004 Mark Richters, University of Bremen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */package org.tzi.use.parser.ocl; }// ------------------------------------// USE parser// ------------------------------------{import java.util.List;import java.util.ArrayList;import java.util.HashMap;import java.io.PrintWriter;import org.tzi.use.parser.MyToken;import org.tzi.use.parser.ParseErrorHandler;}class GOCLParser extends Parser;options { exportVocab = GOCL; defaultErrorHandler = true; buildAST = false; k = 5; //codeGenMakeSwitchThreshold = 2; //codeGenBitsetTestThreshold = 3;} { final static String Q_COLLECT = "collect"; final static String Q_SELECT = "select"; final static String Q_REJECT = "reject"; final static String Q_FORALL = "forAll"; final static String Q_EXISTS = "exists"; final static String Q_ISUNIQUE = "isUnique"; final static String Q_SORTEDBY = "sortedBy"; final static String Q_ANY = "any"; final static String Q_ONE = "one"; final static int Q_COLLECT_ID = 1; final static int Q_SELECT_ID = 2; final static int Q_REJECT_ID = 3; final static int Q_FORALL_ID = 4; final static int Q_EXISTS_ID = 5; final static int Q_ISUNIQUE_ID = 6; final static int Q_SORTEDBY_ID = 7; final static int Q_ANY_ID = 8; final static int Q_ONE_ID = 9; final static HashMap queryIdentMap = new HashMap(); static { queryIdentMap.put(Q_COLLECT, new Integer(Q_COLLECT_ID)); queryIdentMap.put(Q_SELECT, new Integer(Q_SELECT_ID)); queryIdentMap.put(Q_REJECT, new Integer(Q_REJECT_ID)); queryIdentMap.put(Q_FORALL, new Integer(Q_FORALL_ID)); queryIdentMap.put(Q_EXISTS, new Integer(Q_EXISTS_ID)); queryIdentMap.put(Q_ISUNIQUE, new Integer(Q_ISUNIQUE_ID)); queryIdentMap.put(Q_SORTEDBY, new Integer(Q_SORTEDBY_ID)); queryIdentMap.put(Q_ANY, new Integer(Q_ANY_ID)); queryIdentMap.put(Q_ONE, new Integer(Q_ONE_ID)); } protected boolean isQueryIdent(Token t) { return queryIdentMap.containsKey(t.getText()); } private int fNest = 0; public void traceIn(String rname) throws TokenStreamException { for (int i = 0; i < fNest; i++) System.out.print(" "); super.traceIn(rname); fNest++; } public void traceOut(String rname) throws TokenStreamException { fNest--; for (int i = 0; i < fNest; i++) System.out.print(" "); super.traceOut(rname); } public void init(ParseErrorHandler handler) { fParseErrorHandler = handler; } /* Overridden methods. */ private ParseErrorHandler fParseErrorHandler; public void reportError(RecognitionException ex) { fParseErrorHandler.reportError( ex.getLine() + ":" +ex.getColumn() + ": " + ex.getMessage()); }}// grammar start/* ------------------------------------ paramList ::= "(" [ variableDeclaration { "," variableDeclaration } ] ")"*/paramList returns [List paramList]{ ASTVariableDeclaration v; paramList = new ArrayList(); }: LPAREN ( v=variableDeclaration { paramList.add(v); } ( COMMA v=variableDeclaration { paramList.add(v); } )* )? RPAREN ;/* ------------------------------------ idList ::= id { "," id }*/idList returns [List idList]{ idList = new ArrayList(); }: id0:IDENT { idList.add((MyToken) id0); } ( COMMA idn:IDENT { idList.add((MyToken) idn); } )* ;/* ------------------------------------ variableDeclaration ::= id ":" type*/variableDeclaration returns [ASTVariableDeclaration n]{ ASTType t; n = null; }: name:IDENT COLON t=type { n = new ASTVariableDeclaration((MyToken) name, t); } ;/* ------------------------------------ expressionOnly ::= conditionalImpliesExpression*/expressionOnly returns [ASTExpression n]{ n = null; }: n=expression EOF ;/* ------------------------------------ expression ::= { "let" id [ : type ] "=" expression "in" } conditionalImpliesExpression*/expression returns [ASTExpression n]{ ASTLetExpression prevLet = null, firstLet = null; ASTType t = null; ASTExpression e1, e2; n = null; }: { MyToken tok = (MyToken) LT(1); /* remember start of expression */ } ( "let" name:IDENT ( COLON t=type )? EQUAL e1=expression "in" { ASTLetExpression nextLet = new ASTLetExpression((MyToken) name, t, e1); if ( firstLet == null ) firstLet = nextLet; if ( prevLet != null ) prevLet.setInExpr(nextLet); prevLet = nextLet; } )* n=conditionalImpliesExpression { if ( n != null ) n.setStartToken(tok); if ( prevLet != null ) { prevLet.setInExpr(n); n = firstLet; n.setStartToken(tok); } } ;/* ------------------------------------ conditionalImpliesExpression ::= conditionalOrExpression { "implies" conditionalOrExpression }*/conditionalImpliesExpression returns [ASTExpression n]{ ASTExpression n1; n = null; }: n=conditionalOrExpression ( op:"implies" n1=conditionalOrExpression { n = new ASTBinaryExpression((MyToken) op, n, n1); } )* ;/* ------------------------------------ conditionalOrExpression ::= conditionalXOrExpression { "or" conditionalXOrExpression }*/conditionalOrExpression returns [ASTExpression n]{ ASTExpression n1; n = null; }: n=conditionalXOrExpression ( op:"or" n1=conditionalXOrExpression { n = new ASTBinaryExpression((MyToken) op, n, n1); } )* ;/* ------------------------------------ conditionalXOrExpression ::= conditionalAndExpression { "xor" conditionalAndExpression }*/conditionalXOrExpression returns [ASTExpression n]{ ASTExpression n1; n = null; }: n=conditionalAndExpression ( op:"xor" n1=conditionalAndExpression { n = new ASTBinaryExpression((MyToken) op, n, n1); } )* ;/* ------------------------------------ conditionalAndExpression ::= equalityExpression { "and" equalityExpression }*/conditionalAndExpression returns [ASTExpression n]{ ASTExpression n1; n = null; }: n=equalityExpression ( op:"and" n1=equalityExpression { n = new ASTBinaryExpression((MyToken) op, n, n1); } )* ;/* ------------------------------------ equalityExpression ::= relationalExpression { ("=" | "<>") relationalExpression }*/equalityExpression returns [ASTExpression n]{ ASTExpression n1; n = null; }: n=relationalExpression ( { MyToken op = (MyToken) LT(1); } (EQUAL | NOT_EQUAL) n1=relationalExpression { n = new ASTBinaryExpression(op, n, n1); } )* ;/* ------------------------------------ relationalExpression ::= additiveExpression { ("<" | ">" | "<=" | ">=") additiveExpression }*/relationalExpression returns [ASTExpression n]{ ASTExpression n1; n = null; }: n=additiveExpression ( { MyToken op = (MyToken) LT(1); } (LESS | GREATER | LESS_EQUAL | GREATER_EQUAL) n1=additiveExpression { n = new ASTBinaryExpression(op, n, n1); } )* ;/* ------------------------------------ additiveExpression ::= multiplicativeExpression { ("+" | "-") multiplicativeExpression }*/additiveExpression returns [ASTExpression n]{ ASTExpression n1; n = null; }: n=multiplicativeExpression ( { MyToken op = (MyToken) LT(1); } (PLUS | MINUS) n1=multiplicativeExpression { n = new ASTBinaryExpression(op, n, n1); } )* ;/* ------------------------------------ multiplicativeExpression ::= unaryExpression { ("*" | "/" | "div") unaryExpression }*/multiplicativeExpression returns [ASTExpression n]{ ASTExpression n1; n = null; }: n=unaryExpression ( { MyToken op = (MyToken) LT(1); } (STAR | SLASH | "div") n1=unaryExpression { n = new ASTBinaryExpression(op, n, n1); } )* ;/* ------------------------------------ unaryExpression ::= ( "not" | "-" | "+" ) unaryExpression | postfixExpression*/unaryExpression returns [ASTExpression n]{ n = null; }: ( { MyToken op = (MyToken) LT(1); } ("not" | MINUS | PLUS ) n=unaryExpression { n = new ASTUnaryExpression((MyToken) op, n); } ) | n=postfixExpression ;/* ------------------------------------ postfixExpression ::= primaryExpression { ( "." | "->" ) propertyCall }*/postfixExpression returns [ASTExpression n]{ boolean arrow; n = null; }: n=primaryExpression ( ( ARROW { arrow = true; } | DOT { arrow = false; } ) n=propertyCall[n, arrow] )* ;/* ------------------------------------ primaryExpression ::= literal | propertyCall | "(" expression ")" | ifExpression Note: propertyCall includes variables*/primaryExpression returns [ASTExpression n]{ n = null; }: n=literal | n=propertyCall[null, false] | LPAREN n=expression RPAREN | n=ifExpression // HACK: the following requires k=3 | id1:IDENT DOT "allInstances" { n = new ASTAllInstancesExpression((MyToken) id1); } ;/* ------------------------------------ propertyCall ::= queryId "(" [ elemVarsDeclaration "|" ] expression ")" | "iterate" "(" elemVarsDeclaration ";" variableInitialization "|" expression ")" | id [ "(" actualParameterList ")" ] Note: source may be null (see primaryExpression).*/propertyCall[ASTExpression source, boolean followsArrow] returns [ASTExpression n]{ n = null; }: // this semantic predicate disambiguates operations from // iterate-based expressions which have a different syntax (the // OCL grammar is very loose here). { isQueryIdent(LT(1)) }? n=queryExpression[source] | n=iterateExpression[source] | n=operationExpression[source, followsArrow] | n=typeExpression[source, followsArrow] ;/* ------------------------------------ queryExpression ::= ("select" | "reject" | "collect" | "exists" | "forAll" | "isUnique" | "sortedBy" ) "(" [ elemVarsDeclaration "|" ] expression ")"*/// Using lookahead k=2 instead of a syntactic predicate for// disambiguating between variableDeclaration and expression (both may// start with an IDENT) seems to be the better alternative in// queryOperation. It avoids guessing (k=1) which turns off actions in// almost all rules and blows up the generated parser.queryExpression[ASTExpression range] returns [ASTExpression n]{ ASTElemVarsDeclaration decls = new ASTElemVarsDeclaration(); n = null; }: op:IDENT LPAREN ( decls=elemVarsDeclaration BAR )? // requires k=2 n=expression RPAREN { n = new ASTQueryExpression((MyToken) op, range, decls, n); } ;/* ------------------------------------ iterateExpression ::= "iterate" "(" elemVarsDeclaration ";" variableInitialization "|" expression ")"*/iterateExpression[ASTExpression range] returns [ASTExpression n]{ ASTElemVarsDeclaration decls = null; ASTVariableInitialization init = null; n = null;}: i:"iterate" LPAREN decls=elemVarsDeclaration SEMI init=variableInitialization BAR n=expression RPAREN { n = new ASTIterateExpression((MyToken) i, range, decls, init, n); } ;/* ------------------------------------ operationExpression ::= id ( ("[" id "]") | ( [ "@" "pre" ] [ "(" [ expression { "," expression } ] ")" ] ) )*/// Operations always require parentheses even if no arguments are// required. This makes it easier, for example, to distinguish a// class-defined operation from an attribute access operation where// both operations may have the same name.operationExpression[ASTExpression source, boolean followsArrow] returns [ASTOperationExpression n]{ ASTExpression e; n = null; }: name:IDENT { n = new ASTOperationExpression((MyToken) name, source, followsArrow); } ( LBRACK rolename:IDENT RBRACK { n.setExplicitRolename((MyToken) rolename); })? ( AT "pre" { n.setIsPre(); } ) ? ( LPAREN { n.hasParentheses(); } ( e=expression { n.addArg(e); } ( COMMA e=expression { n.addArg(e); } )* )? RPAREN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -