-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhwcompile.y
67 lines (62 loc) · 1.74 KB
/
hwcompile.y
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
%{
package main
import("os"; "os/exec"; "io"; "text/scanner"; "fmt"; "strings"; "regexp")
var program string
var errstate bool=false
const COMPILER="/bin/g++"
%}
%union {
value string
}
%type <value> top;
%type <value> list;
%type <value> command;
%token <value> STRING;
%token HWCOMMAND;
%token EOF;
%%
top : list
{ program=fmt.Sprintf("#include<iostream>\nint main(){%v\n}", $1); }
;
list : /* empty */
{ $$=""; }
| list command
{ $$=fmt.Sprintf("%v\n\t%v", $1, $2); }
;
command : HWCOMMAND ';'
{ $$=fmt.Sprintf("std::cout<<\"Hello, World!\"<<std::endl;"); }
| HWCOMMAND STRING ';'
{ $$=fmt.Sprintf("std::cout<<\"Hello, %v!\"<<std::endl;", $2); }
;
%%
type MainLex struct{ scanner.Scanner }
func (x *MainLex) Error(s string){fmt.Printf("ERROR: Parse: %s.\n", s); errstate=true}
func(l *MainLex)Lex(lval *yySymType)int{
token, lit := l.Scan(), l.TokenText()
//fmt.Printf("\tToken: %-10v\tliteral: %-15s\n", scanner.TokenString(token), lit)
switch int(token){
case scanner.Ident: if(lit=="helloworld") { return HWCOMMAND; }
case scanner.String: lval.value=strings.Trim(lit, `"`); return STRING;
case scanner.EOF: return 0;
}
return int(token)
}
func yyCompile(){
if(errstate){return};
app:=regexp.MustCompile(`(.*)(\.hw)$`).ReplaceAllString(os.Args[1], `$1.out`)
gcc:=exec.Command(COMPILER, "-o", app, "-x", "c++", "-")
stdin, _:=gcc.StdinPipe()
go func(){defer stdin.Close(); io.WriteString(stdin, program)}()
_, err:=gcc.CombinedOutput()
if err!=nil{fmt.Printf("ERROR: %s\n", err)}
}
func main() {
if len(os.Args)==1{fmt.Println("Usage:", os.Args[0], "[FILE.hw]"); return}
file, err:=os.Open(os.Args[1])
if err!=nil{fmt.Printf("Input file not found.\n")}
defer file.Close()
lx:=new(MainLex)
lx.Init(file)
yyParse(lx)
yyCompile()
}