Hi All
Now I struggling to construct a compiler for a simple grammar as show
below, which doesn't include type checking, in two passes, front
end(semantic analyzer) and back end.
At first I started to construct the semantic analyzer and it seems run
correctly but the part of function declarations didn't work( may be
because there is no semantic actions associated with it so I am little
confused).
So the following is a part of the grammar related to function declarations :
Productions
program = fdecls main_st
;
main_st = main body
;
fdecls =
{multi_fdecls} fdecls fdecl |
{no_fdecl}
;
fdecl = fhead body
;
fhead = fid lpar param_action rpar
;
fid = id
;
param_action = params
;
params =
{multi_params} params comma id |
{one_param} id |
{no_param}
;
body = lbra vdaction stmts rbra
;
I implemented the above grammar in the following segment of code But I
couldn't find where the mistakes( but I am confused about the semantic
action for that part) :
1 package cmm;
2 import cmm.analysis.*;
3 import cmm.node.*;
4 import cmm.*;
5 import java.util.*;
6
7 class Semantic extends DepthFirstAdapter {
8 public Hashtable table = new Hashtable(10001);
9 private SymMnger2 st;
10 private int level;
11
12 Semantic(SymMnger2 st) {
13 this.st = st;
14 }
15
16 public void outAProgram(AProgram node) {
17 Information i1 = (Information)table.get(node.getFdecls());
18 Information i2 = (Information)table.get(node.getMainSt());
19 Information info = new Information();
20
21 info.addChild(i1);
22 info.addChild(i2);
23 //info.printInfo();
24 }
25
26 public void outAMainSt(AMainSt node) {
27 Information info = (Information)table.get(node.getBody());
28 table.put(node, info);
29 }
30
31 public void outAMultiFdeclsFdecls(AMultiFdeclsFdecls node) {
32 Information i1 = (Information)table.get(node.getFdecls());
33 Information i2 = (Information)table.get(node.getFdecl());
34 Information info = new Information();
35
36 info.addChild(i1);
37 info.addChild(i2);
38 table.put(node, info);
39 }
40
41 public void outANoFdeclFdecls(ANoFdeclFdecls node) {
42 Information info = new Information();
43 table.put(node, info);
44 }
45
46 public void outAFdecl(AFdecl node) {
47 Information i1 = (Information)table.get(node.getFhead());
48 Information i2 = (Information)table.get(node.getBody());
49 Information info = new Information();
50
51 info.addChild(i1);
52 info.addChild(i2);
53 table.put(node, info);
54 }
55
56 public void outAFhead(AFhead node) {
57 Information i1 = (Information)table.get(node.getFid());
58 Information i2 = (Information)table.get(node.getParamAction());
59 st.proc_params(i2.getVal());
60 Information info = new Information();
61 info.addChild(i1);
62 info.addChild(i2);
63 table.put(node, info);
64 }
65
66 public void outAFid(AFid node) {
67 String name = node.getId().getText();
68
69 if (st.searchAll(name) == null){
70 st.registName(name, SymMnger2.FUNC, st.getLevel(), 0);
71 }
72 else {
73 System.out.println("This identifier has been already
declared(4)!");
74 System.exit(0);
75 }
76 st.registName("block", SymMnger2.BLOCK, 0, 0);
77 }
78
79 public void inAParamAction(AParamAction node) {
80 st.setLevel(level++);
81 }
82
83 public void outAParamAction(AParamAction node) {
84 Information info = (Information)table.get(node.getParams());
85 st.setLevel(level--);
86 table.put(node, info);
87 }
88
89 public void outAMultiParamsParams(AMultiParamsParams node) {
90 String name = node.getId().getText();
91
92 if (st.searchCurrent(name) == null){
93 st.registName(name, SymMnger2.VAR, st.getLevel(), 0);
94 } else {
95 System.out.println("This identifier has been already " +
96 "declared(p1)!");
97 System.exit(0);
98 }
99
100 Information i = (Information)table.get(node.getParams());
101 Information info = new Information(i.getVal()+1);
102 table.put(node, info);
103 }
104
105 public void outAOneParamParams(AOneParamParams node) {
106 String name = node.getId().getText();
107
108 if (st.searchCurrent(name) == null) {
109 st.registName(name, SymMnger2.VAR, st.getLevel(), 0);
110 }
111 else {
112 System.out.println("This identifier has been already" +
113 "declared(p2)!");
114 System.exit(0);
115 }
116
117 Information info = new Information(1);
118 table.put(node, info);
119 }
120
121 public void outANoParamParams(ANoParamParams node) {
122 Information info = new Information(0);
123 table.put(node, info);
124 }
125
126 public void inABody(ABody node) {
127 st.enterScope();
128 }
129
130 public void outABody(ABody node) {
131 Information i1 = (Information)table.get(node.getVdaction());
132 Information i2 = (Information)table.get(node.getStmts());
133 Information info = new Information();
134
135 info.addChild(i1);
136 info.addChild(i2);
137 table.put(node, info);
138 st.leaveScope();
139 }
140
Also I mention the following part of grammar of expression because it
contains the nonterminal factor which has many alternatives, one of
them is about function paramaters
expression =
{explus} expression plus term |
{exminus} expression minus term |
{exterm} term
;
term =
{termmult} term mult factor |
{termdiv} term div factor |
{termfactor} factor
;
factor =
{factid} id |
{factfc} id lpar fparams rpar |
{factnum} number |
{factparen} lpar expression rpar
;
fparams =
{fparams} fparams comma fparam |
{fparam} fparam |
{noparam}
;
fparam = expression
;
SoI concentrate about the part related to fuction paramaters which I
implemented it like :
459 public void outAFactfcFactor(AFactfcFactor node) {
460 String name = node.getId().getText();
461 Lst list = st.searchAll(name);
462
463 if (list == null){
464 System.out.println("This identifier (" +
465 name +
466 ") is not declared!!(f3)");
467 System.exit(0);
468 }
469
470 if (list.getKind() != SymMnger2.FUNC){
471 System.out.println("This identifier (" +
472 name +
473 ") is not declared as function");
474 System.exit(0);
475 }
476
477 Information i1 = (Information)table.get(node.getFparams());
478 Information i2 = new Information(list);
479
480 if (list.getParams() != i1.getVal()){
481 System.out.println("The number of parameters does not match" +
482 " as the declaration(" + name +
483 " : " +
484 list.getParams() +
485 " -> " +
486 i1.getVal() +
487 ")");
488 System.exit(0);
489 }
490 Information info = new Information();
491 info.addChild(i1);
492 info.addChild(i2);
493 table.put(node, info);
494 }
495
.
.
.
508 public void outAFparamsFparams(AFparamsFparams node) {
509 Information i1 = (Information)table.get(node.getFparams());
510 Information i2 = (Information)table.get(node.getFparam());
511 Information info = new Information(i1.getVal()+i2.getVal());
512 table.put(node, info);
513 }
514
515 public void outAFparamFparams(AFparamFparams node) {
516 Information info = new Information(1);
517 table.put(node, info);
518 }
519
520 public void outANoparamFparams(ANoparamFparams node) {
521 Information info = new Information(0);
522 table.put(node, info);
523 }
524
525 public void outAFparam(AFparam node) {
526 Information info = (Information)table.get(node.getExpression());
527 table.put(node, info);
528 }
529 }
So at first to design the semantic analyzer, I have to decide what the
semantic actions needed at each node
as in the following :
1. Because my grammar doesn't contain type checking it would be easy
since the attributes maybe is the token name only for identifiers, but
I constructed Lst class to
include 4 attributes(name, kind, level,params)for the identifier also
level is used for scoping and
kind represents 4 cases VAR, FUNC, BLOCK, AND CONST and params ,
which is the number
of paramaters of the procedure. in addition to the attribute, Val,
which denotes the number of variables.
2. I have to evaluate the part of expressions
3 the procedure attribute which is params,
so for example in the case of identifer params = 0, and check if
paramaters of return expression matches
the number of arguments of function declaration.
4. My confused is here , do I have to add semantic actions for if
statement and while statement (of course including condition part)at
this step or can I delay that for back end step.
Also I designed Information class , the information which will be
added at each node and SymMnger2 class for managing symbol table in
addition to Lst classed which I menetioned about it before.
Is the above steps ok to implement the semantic analyzer?
According to the above grammar and above steps, I designed the semantic
analyzer.
I send it because I am really confused about what I have to do exactly
to implement semantic analyzer.
and I ask if any body can help to clarify every thing in
implementaion process and to check if what I did
is correct or not and try to help in finding my mistakes in my
program( the part related to procedure declaration and maybe other
parts) so I associated the following files:
1. Lst.java, which include attibutes for identifier, block, constant,
and fuction
2. SymMnger2.java, which construct the symbol table
3. Information.java. which is used to add the sematic
actions(inforamtions) on the nodes of the tree.
4. Semantic.java, which is the semantic analyzer.
5. SematicTest.java for testing
6. cmm.grammar.
I have tried to write the problem short as possible as I can,
So please take it easy and try to help me to understand , even if it
takes from you several emails till I manage and understand.
thanks in advance
Attachment:
cmm.grammar
Description: Binary data
Attachment:
Information.java
Description: Binary data
Attachment:
Lst.java
Description: Binary data
Attachment:
Semantic.java
Description: Binary data
Attachment:
SemanticTest.java
Description: Binary data
Attachment:
SymMnger2.java
Description: Binary data