-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathparser.cup
More file actions
94 lines (81 loc) · 4.11 KB
/
parser.cup
File metadata and controls
94 lines (81 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import java_cup.runtime.*;
parser code {:
Scanner s;
Parser(Scanner s){ this.s=s; }
:}
/* define how to connect to the scanner! */
scan with {: return s.next_token(); :};
/* Symbol Lists */
/* Terminals (tokens returned by the scanner). */
terminal PLUS, LPAREN, RPAREN, LBRACK, RBRACK, COMMA, IF, ELSE, PREFIX, REVERSE, IDENT;
terminal String STRING_LITERAL; // our scanner provides numbers as strings
/* Non terminals */
non terminal begin, fdecl, decl, fcall, declname, body, declargs, callname, callargs,
ifbody, cond, str, strfcall, bodyfcall, ifbodyfcall, condfcall, callnameinf, callargsinf;
/* Precedence Declarations */
precedence left IF;
precedence left PLUS;
precedence left REVERSE;
/* The Grammar Rules */
begin ::= fdecl:fd fcall:fc {: System.out.println("public static void main(String[] args){\n"+fc+"\n}\n");
System.out.println(fd); :}
;
/* FUNCTION DECLARATION */
fdecl ::= fdecl:fd decl:d {: RESULT = fd+"\n\n"+d; :}
|decl:d {: RESULT = d; :}
;
decl ::= declname:d body:b RBRACK {: RESULT = "public static String "+d+"{\n"+ "\t return ("+b+");"+"\n}"; :}
;
declname ::= IDENT:i LPAREN declargs:d RPAREN LBRACK {: RESULT = i+"("+d+")"; :}
|IDENT:i LPAREN RPAREN LBRACK {: RESULT = i+"()"; :}
;
declargs ::= declargs:d COMMA IDENT:i {: RESULT = d+", "+"String "+i; :}
|IDENT:i {: RESULT = "String "+i; :}
;
/* FUNCTION CALL */
fcall ::= bodyfcall:b fcall:fc {: RESULT = "\tSystem.out.println("+b+");\n"+fc; :}
|bodyfcall:b {: RESULT = "\tSystem.out.println("+b+");"; :}
;
callname ::= IDENT:i LPAREN callargs:c RPAREN {: RESULT = i+"("+c+")"; :}
|IDENT:i LPAREN RPAREN {: RESULT = i+"()"; :}
;
callargs ::= callargs:c COMMA bodyfcall:b {: RESULT = c+", "+b; :}
|bodyfcall:b {: RESULT = b; :}
;
bodyfcall ::= bodyfcall:b PLUS strfcall:s {: RESULT = "("+b+")"+"+("+s+")"; :}
|strfcall:s {: RESULT = s; :}
;
strfcall ::= STRING_LITERAL:s {: RESULT = "\""+s+"\""; :}
|ifbodyfcall:b {: RESULT = b; :}
|callname:f {: RESULT = f; :}
|REVERSE strfcall:s {: RESULT = "reversefunc("+s+")"; :}
;
/* OTHERS */
body ::= body:b PLUS str:s {: RESULT = "("+b+")"+"+("+s+")"; :}
|str:s {: RESULT = s; :}
;
str ::= STRING_LITERAL:s {: RESULT = "\""+s+"\""; :}
|IDENT:i {: RESULT = i; :}
|ifbody:b {: RESULT = b; :}
|callnameinf:f {: RESULT = f; :}
|REVERSE str:s {: RESULT = "reversefunc("+s+")"; :}
;
/* FUNCTION IN BODY FUNCTION ALLOWS ID */
callnameinf ::= IDENT:i LPAREN callargsinf:c RPAREN {: RESULT = i+"("+c+")"; :}
|IDENT:i LPAREN RPAREN {: RESULT = i+"()"; :}
;
callargsinf ::= callargsinf:c COMMA body:b {: RESULT = c+", "+b; :}
|body:b {: RESULT = b; :}
;
/* IF ELSE FOR BODY */
ifbody ::= IF LPAREN cond:c RPAREN
body:b1 ELSE body:b2 {: RESULT = c+" ? "+b1+" : "+b2; :}
;
cond ::= str:s1 PREFIX str:s2 {: RESULT = s2+".startsWith("+s1+")";:}
;
/* IF ELSE FOR FUNCTION CALL */
ifbodyfcall ::= IF LPAREN condfcall:c RPAREN
bodyfcall:b1 ELSE bodyfcall:b2 {: RESULT = c+" ? "+b1+" : "+b2; :}
;
condfcall ::= strfcall:s1 PREFIX strfcall:s2 {: RESULT = s2+".startsWith("+s1+")"; :}
;