Java程序辅导

C C++ Java Python Processing编程在线培训 程序编写 软件开发 视频讲解

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439
Discussion 1
CSE 131
introduction
See course page for the lab hour schedule.
We are available at our lab hours, or by 
appointment. Feel free to email us.
overview
● purpose of our discussions
● starter code
● STOs and types
● error reporting
● functions
requisite prior knowledge
● object oriented design
● inheritance
● polymorphism
● some C
● some assembly (for project 2)
compilation phases
● lexical analysis
○ parsing of tokens - not a major point of this course
○ Lexer.java
● syntactic and semantic analysis
○ project 1 focuses on semantics (does the code make 
sense?)
○ rc.cup and MyParser.java
● code generation
○ project 2
starter code
● /home/solaris/ieng9/cs131s/public/starterCode/
● look through the files and become familiar 
with them
● the GETTING_STARTED and 
CUP_Overview files are helpful
important files
rc.cup contains the parser’s rules and action 
code
Designator2 ::= 
Designator2:_1 T_DOT T_ID:_3
{:
RESULT = ((MyParser) parser).DoDesignator2_Dot (_1, _3);
:}
| Designator2:_1 T_LBRACKET ExprList T_RBRACKET
{:
RESULT = ((MyParser) parser).DoDesignator2_Array (_1);
:}
;
cup syntax
Designator2 ::= 
Designator2:LABEL T_DOT T_ID:LABEL
{:
ACTION CODE GOES HERE
:}
| Designator2:_1 T_LBRACKET ExprList T_RBRACKET
{:
// RESULT is the “return” value of the rule
RESULT = _1;
:}
;
important files
MyParser.java contains methods for semantic 
analysis
STO DoDesignator3_ID (String strID)
{
STO sto;
if ((sto = m_symtab.access (strID)) == null)
{
m_nNumErrors++;
m_errors.print (Formatter.toString(ErrorMsg.undeclared_id, strID));
sto = new ErrorSTO (strID);
}
return (sto);
}
important files
SymbolTable.java contains functions that 
support scopes
(Contains one of the problems that will be fixed 
in phase 0)
parse tree example
auto x = 2; Program
OptGlobalDecls
GlobalDecls
VarDecl
OpStatic T_AUTO ExprT_ID
T_STATIC
T_SEMI
Expr0...Expr8
Designator
Designator1...Designator3
T_INT_LITERAL
T_ASSIGN
sto hierarchy
● you can change this around
● look at the methods in each and how they 
are overloaded (e.g., isVar(), isConst())
STO
FuncSTO TypedefSTO ExprSTO VarSTOConstSTO ErrorSTO
sto hierarchy
● all STOs have fields to indicate modifiability 
and addressability
○ whenever you create an STO instance, make sure to 
set these appropriately
● ConstSTO includes a value field
○ used for constant folding (more on this later)
types
Type ::= 
SubType OptModifierList OptArrayDef
| T_FUNCPTR T_COLON ReturnType T_LPAREN OptParamList:_3 T_RPAREN
;
SubType ::= 
QualIdent
| BasicType
;
                  
BasicType ::= 
T_INT
| T_FLOAT
| T_BOOL
| T_CHAR
;
types
● need to create objects for
○ basic types
○ array types
○ struct types (only done in structdef)
○ pointer types
○ function pointer types
● how can they be organized to make our lives 
easier?
● what methods and fields should we provide 
within each?
possible type hierarchy
Type
BasicType VoidType CompositeType
NumericType BoolType
IntType FloatType
ArrayType StructType PointerGroupType
FunctionPointerTypePointerType
NullPointerType
useful methods on types
● look at how the STO files are written
● consider making methods like
○ isNumeric()
○ isFloat()
○ isInt()
○ isArray()
○ etc
● even better, use Java’s instanceof operator
○ e.g. obj instanceof NumericType
useful methods on types
● all types would benefit from methods like:
○ isAssignableTo(Type t) - coercible type (int -> float)
○ isEquivalentTo(Type t) - same type
● some types will need to store more info
○ ArrayType may need dimensions
○ StructType may need a list of member fields
○ size of the type for sizeof
setting types
● must ensure all STOs have a type field
○ make sure this field is set properly when the type 
becomes known
● what changes need to be made to the rc.cup 
and MyParser.java files?
type setting example
● we want to incorporate the type, so we pass 
it to the MyParser method
VarDecl ::= OptStatic UndecoratedType IdentListWOptInit:_3 T_SEMI
{:
((MyParser)parser).DoVarDecl(_3);
:}
type setting example
now, in MyParser.java
void DoVarDecl (Vector lstIDs, Type t)
{
for (int i = 0; i < lstIDs.size (); i++)
{
String id = (String) lstIDs.elementAt (i);
if (m_symtab.accessLocal (id) != null)
{
m_nNumErrors++;
m_errors.print(Formatter.toString(ErrorMsg.redeclared_id, id));
}
VarSTO sto = new VarSTO (id);
// Add code here to set sto’s type field
m_symtab.insert (sto);
}
}
type checking
● now that our STOs have types, how do we 
check them?
type checking example
● consider the following code:
● let’s focus on y = x + 12.5
int x;
float y;
function : void main() {
x = 5; // ok
y = x + 12.5; // ok
x = y; // error
}
type checking example
Currently rc.cup has:
● What needs to be done?
○ based on AddOp (+, -) we need to check the types of 
_1 and _3
○ then create a new STO (an ExprSTO) to return as 
the result
Expr7 ::= Expr7:_1 AddOp:_2 Expr8:_3
{:
RESULT = _1;
:}
type checking example
● getting the type out of an STO?
● have STO a and want to check type 
equivalence to some STO b?
○ a.getType().isEquivalentTo(b.getType())
important themes
● don’t just throw code into the files
● think about the current problem at hand
● think about upcoming tasks
● try to make your code as general as possible
● project 2 (assembly generation) will be 
based off project 1, so the more forethought 
you put into project 1 the easier project 2 will 
be
an idea
● define a new function inside MyParser to 
check expressions
● define Operator classes to assist type 
checking
// in MyParser.java
STO DoBinaryExpr(STO a, Operator o, STO b) {
STO result = o.checkOperands(a, b);
if (result instanceof ErrorSTO) {
// do stuff
}
return result ;
}
operator hierarchy
● probably the most important hierarchy of this 
assignment, one possible setup:
Operator
BinaryOp UnaryOp
ArithmeticOp BooleanOp BitwiseOp ComparisonOp
NotOp,
IncOp,
DecOp
AddOp,
MinusOp,
etc
AndOp
OrOp
BwAndOp,
BwOrOp,
XorOp
EqualOp,
NotEqualOp,
LessThanOp,
etc
an idea
In each operator class, we can do something 
like this:
STO checkOperands(STO a, STO b) {
aType = a.getType();
bType = b.getType();
if (!(aType instanceof NumericType) || !(bType  instanceof NumericType)) {
// error
return new ErrorSTO(...);
} else if (aType instanceof IntType && bType instanceof IntType) {
// return ExprSTO of int type
} else {
// return ExprSTO of float type
}
}
error reporting
● now that we can check types, we will find 
errors
● once found, they need to be printed out
● use only the provided error messages in 
ErrorMsg.java
error reporting
● only report the FIRST error found in each 
statement
● if you want to see the line number where the 
error occurred (for debugging only) use 
“make debug”
ErrorSTO
● looks just like any other STO
● when you find an error, make the result an 
ErrorSTO
○ this provides a signal to higher level rules that an 
error happened below them somewhere
○ use that signal to know when to stop further checks 
within in the statement
functions
● some fundamental points
○ we are writing a static translator, not an interpreter
○ once we finish the function declaration, including the 
body, we’re done with it
■ don’t need to remember code in the body
■ in project 2 you’ll spit out assembly code for it
○ function calls will boil down to an assembly “call foo” 
sort of instruction
functions
● for project 1
○ check the function call against the function 
declaration to ensure argument symmetry
○ do type checking on the statements in the body of 
the function
○ check the return logic of the function, including 
return by reference
○ allow function overloading (extra credit)
FuncSTO
● store some information about the function
○ return type
■ separate from the full type of the function itself, 
which is actually a function pointer type
○ flag for return by reference
○ parameter information
■ total number of parameters
■ type of each parameter, including pass-by-
reference or not
function definition
FuncDef ::= 
T_FUNCTION T_COLON ReturnType OptRef T_ID:_2
{: 
((MyParser) parser).DoFuncDecl_1(_2); 
:}
T_LPAREN OptParamList:_3 T_RPAREN
{: 
((MyParser) parser).DoFormalParams(_3); 
:}
T_LBRACE OptStmtList T_RBRACE
{: 
((MyParser) parser).DoFuncDecl_2(); 
:}
;
function definition
void DoFuncDecl_1(String id) {
if (m_symtab.accessLocal(id) != null) {
m_nNumErrors++;
m_errors.print(Formatter.toString(ErrorMsg.redeclared_id, id));
}
FuncSTO sto = new FuncSTO(id);
m_symtab.insert(sto); // Inserted into current scope
m_symtab.openScope(); // New scope opened
m_symtab.setFunc(sto); // Current function we’re in is set
}
function definition
void DoFuncDecl_2() {
m_symtab.closeScope(); // Close scope (pops top scope off)
m_symtab.setFunc(null); // Says we’re back in outer scope
}
function definition
● In this example
○ we need to make a FuncSTO with
■ name foo
■ return type boolean
■ parameter count
■ parameters: value float, value float, reference 
float
function : bool foo(float a, float b, float &c) {
bool x;
x = a > b;
x = (a + c) <= 2;
return x;
}
function definition
● further, we need to insert VarSTOs for a, b, 
and c into the symbol table so the code in 
the body can use them
function : bool foo(float a, float b, float &c) {
bool x;
x = a > b;
x = (a + c) <= 2;
return x;
}
function calls
● now that we have a type checked FuncSTO 
in the symbol table, we are ready to call it
foo(1, 2, 3.3)
● given the call above, we’d have an error 
since 3.3 is not addressable (for the ref 
param)
function calls
● when we call a function
○ get the matching FuncSTO from the symbol table 
and check its parameters with the arguments at the 
callsite
● consider making a vector of some object to 
hold the parameter info
● important design choices
● remember to think ahead about function 
overloading (extra credit)
function return types
● inside the function body
○ type of the return expression needs to be checked 
against the declared return type of the function
● at the callsite
○ the function call behaves just like any other 
ExprSTO
○ the return type becomes the type of the expression
● functions are the only thing that can have a 
void type
○ void isn’t equivalent or assignable to anything ever 
(including itself)
function return types
● return by value
○ in the function, the return expression just has to be 
assignable to the function’s return type
○ at the callsite, the resulting expression is an rval
● return by reference
○ in the function, the return expression has to have an 
equivalent type AND must be a modifiable lval
○ at the callsite, the resulting expression results in a 
modifiable lval
next steps
● find a partner
○ maybe set up a unix group (see broadcast message)
● set up source control
○ git, svn, etc
○ if using a hosted solution like github or bitbucket, 
make sure the repo is private
● consider using Eclipse
● understand the starter code
○ look through all the files
● do phase 0 and phase 1
next steps
● come to lab hours
○ we’re here for you
● check piazza
○ often other people have the same questions as you 
and they may already be answered