You are to develop an SPA prototype which should allow you to enter a SIMPLE source program and PQL queries. The idea of the prototype is to let you see the main SPA components in simplified form.
Your SPA architecture should be similar to the one described in the course materials (i.e., lecture notes and handouts).
Your source files and directories should be organized and correspond to the SPA architecture.
Your solution should use naming conventions to make correspondences visible.
typedef
can easily assign specific C++ data type to symbolic names.Integrate Autotester with your program. Use Autotester to reuse test cases and automate testing.
You are not allowed to use parser generators or additional libraries (e.g. Bison/Flex/Boost) for parsing SIMPLE source program.
The Source Processor should be able to parse a SIMPLE source program with the following specification.
Lexical tokens:
LETTER: A-Z | a-z - capital or small letter
DIGIT: 0-9
NZDIGIT: 1-9 - non-zero digit
NAME: LETTER (LETTER | DIGIT)* - procedure names and variables are strings of
letters, and digits, starting with a letter
INTEGER : 0 | NZDIGIT ( DIGIT )* - Constants are sequence of digits with no leading zero
Grammar rules:
program: procedure
procedure: 'procedure' proc_name '{' stmtLst '}'
stmtLst: stmt+
stmt: read | print | while | if | assign
read: 'read' var_name';'
print: 'print' var_name';'
while: 'while' '(' cond_expr ')' '{' stmtLst '}'
if: 'if' '(' cond_expr ')' 'then' '{' stmtLst '}' 'else' '{' stmtLst '}'
assign: var_name '=' expr ';'
cond_expr: rel_expr | '!' '(' cond_expr ')' |
'(' cond_expr ')' '&&' '(' cond_expr ')' |
'(' cond_expr ')' '||' '(' cond_expr ')'
rel_expr: rel_factor '>' rel_factor | rel_factor '>=' rel_factor |
rel_factor '<' rel_factor | rel_factor '<=' rel_factor |
rel_factor '==' rel_factor | rel_factor '!=' rel_factor
rel_factor: var_name | const_value | expr
expr: expr '+' term | expr '-' term | term
term: term '*' factor | term '/' factor | term '%' factor | factor
factor: var_name | const_value | '(' expr ')'
var_name, proc_name: NAME
const_value: INTEGER
In particular, a program will only have one procedure, and there are no call statements.
The PKB should store information on design entities.
The PKB should also store information on the following design abstractions:
Follows/Follows*
Parent/Parent*
Modifies
for statementsUses
for statementsYou may use any data structures that you find useful in implementing SPA. Implementations that do not contain an AST are acceptable, as long as all design abstractions and pattern matching are stored and computed correctly.
The Query Processing Subsystem should be able to validate and evaluate the queries with the following specification.
Lexical tokens:
LETTER: A-Z | a-z - capital or small letter
DIGIT: 0-9
NZDIGIT: 1-9 - non-zero digit
IDENT : LETTER ( LETTER | DIGIT )*
NAME : LETTER ( LETTER | DIGIT )*
INTEGER : 0 | NZDIGIT ( DIGIT )* - Constants are sequence of digits with no leading zero
synonym : IDENT
stmtRef : synonym | '_' | INTEGER
entRef : synonym | '_' | '"' IDENT '"'
Grammar rules:
select-cl : declaration* 'Select' synonym [ suchthat-cl ] [ pattern-cl ]
declaration : design-entity synonym (',' synonym)* ';'
design-entity : 'stmt' | 'read' | 'print' | 'while' | 'if' | 'assign' |
'variable' | 'constant' | 'procedure'
suchthat-cl : 'such' 'that' relRef
relRef : Follows | FollowsT | Parent | ParentT | UsesS | ModifiesS
Follows : 'Follows' '(' stmtRef ',' stmtRef ')'
FollowsT : 'Follows*' '(' stmtRef ',' stmtRef ')'
Parent : 'Parent' '(' stmtRef ',' stmtRef ')'
ParentT : 'Parent*' '(' stmtRef ',' stmtRef ')'
UsesS : 'Uses' '(' stmtRef ',' entRef ')'
ModifiesS : 'Modifies' '(' stmtRef ',' entRef ')'
pattern-cl : 'pattern' syn-assign '(' entRef ',' expression-spec ')'
syn-assign : IDENT
expression-spec : '_' '"' factor '"' '_' | '_'
factor: var_name | const_value
var_name: NAME
const_value : INTEGER
In particular, a query will only have at most one such-that clause and one pattern clause in sequence.
You do not need to implement query evaluation for queries with:
Modifies
and Uses
for procedurespattern a(_, _"x + 1"_)
pattern a(_, _"x"_)
and pattern a(_, _"1"_)
pattern a(_, "x")
pattern a(_, _"x"_)
and pattern a(_, _)