Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flag to revert back to the old behavior, for backward compatability. #1

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Go

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:

build:
name: Build
runs-on: ubuntu-latest
steps:

- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: ^1.13
id: go

- name: Check out code into the Go module directory
uses: actions/checkout@v2

- name: Build and Test
run: go run build.go test
16 changes: 15 additions & 1 deletion build.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,19 @@ func grammars_calculator() bool {
return false
}

func grammars_calculator_ast() bool {
if done("grammars/calculator_ast/calculator.peg.go", peg, "grammars/calculator_ast/calculator.peg") {
return true
}

wd := chdir("grammars/calculator_ast/")
defer chdir(wd)

command("../../peg", "", "", "-switch", "-inline", "calculator.peg")

return false
}

func grammars_fexl() bool {
if done("grammars/fexl/fexl.peg.go", peg, "grammars/fexl/fexl.peg") {
return true
Expand Down Expand Up @@ -365,7 +378,8 @@ func grammars_long_test() bool {
}

func test() bool {
if done("", grammars_c, grammars_calculator, grammars_fexl, grammars_java, grammars_long_test) {
if done("", grammars_c, grammars_calculator, grammars_calculator_ast,
grammars_fexl, grammars_java, grammars_long_test) {
return true
}

Expand Down
137 changes: 137 additions & 0 deletions grammars/calculator_ast/calculator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build grammars

package main

import (
"math/big"
)

func (c *Calculator) Eval() *big.Int {
return c.Rulee(c.AST())
}

func (c *Calculator) Rulee(node *node32) *big.Int {
node = node.up
for node != nil {
switch node.pegRule {
case rulee1:
return c.Rulee1(node)
}
node = node.next
}
return nil
}

func (c *Calculator) Rulee1(node *node32) *big.Int {
node = node.up
var a *big.Int
for node != nil {
switch node.pegRule {
case rulee2:
a = c.Rulee2(node)
case ruleadd:
node = node.next
b := c.Rulee2(node)
a.Add(a, b)
case ruleminus:
node = node.next
b := c.Rulee2(node)
a.Sub(a, b)
}
node = node.next
}
return a
}

func (c *Calculator) Rulee2(node *node32) *big.Int {
node = node.up
var a *big.Int
for node != nil {
switch node.pegRule {
case rulee3:
a = c.Rulee3(node)
case rulemultiply:
node = node.next
b := c.Rulee3(node)
a.Mul(a, b)
case ruledivide:
node = node.next
b := c.Rulee3(node)
a.Div(a, b)
case rulemodulus:
node = node.next
b := c.Rulee3(node)
a.Mod(a, b)
}
node = node.next
}
return a
}

func (c *Calculator) Rulee3(node *node32) *big.Int {
node = node.up
var a *big.Int
for node != nil {
switch node.pegRule {
case rulee4:
a = c.Rulee4(node)
case ruleexponentiation:
node = node.next
b := c.Rulee4(node)
a.Exp(a, b, nil)
}
node = node.next
}
return a
}

func (c *Calculator) Rulee4(node *node32) *big.Int {
node = node.up
minus := false
for node != nil {
switch node.pegRule {
case rulevalue:
a := c.Rulevalue(node)
if minus {
a.Neg(a)
}
return a
case ruleminus:
minus = true
}
node = node.next
}
return nil
}

func (c *Calculator) Rulevalue(node *node32) *big.Int {
node = node.up
for node != nil {
switch node.pegRule {
case rulenumber:
a := big.NewInt(0)
a.SetString(string(c.buffer[node.begin:node.end]), 10)
return a
case rulesub:
return c.Rulesub(node)
}
node = node.next
}
return nil
}

func (c *Calculator) Rulesub(node *node32) *big.Int {
node = node.up
for node != nil {
switch node.pegRule {
case rulee1:
return c.Rulee1(node)
}
node = node.next
}
return nil
}
34 changes: 34 additions & 0 deletions grammars/calculator_ast/calculator.peg
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2010 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

package main

type Calculator Peg {
}

e <- sp e1 !.
e1 <- e2 ( add e2
/ minus e2
)*
e2 <- e3 ( multiply e3
/ divide e3
/ modulus e3
)*
e3 <- e4 ( exponentiation e4
)*
e4 <- minus value
/ value
value <- number
/ sub
number <- < [0-9]+ > sp
sub <- open e1 close
add <- '+' sp
minus <- '-' sp
multiply <- '*' sp
divide <- '/' sp
modulus <- '%' sp
exponentiation <- '^' sp
open <- '(' sp
close <- ')' sp
sp <- ( ' ' / '\t' )*
24 changes: 24 additions & 0 deletions grammars/calculator_ast/calculator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build grammars

package main

import (
"math/big"
"testing"
)

func TestCalculator(t *testing.T) {
expression := "( 1 - -3 ) / 3 + 2 * ( 3 + -4 ) + 3 % 2^2"
calc := &Calculator{Buffer: expression}
calc.Init()
if err := calc.Parse(); err != nil {
t.Fatal(err)
}
if calc.Eval().Cmp(big.NewInt(2)) != 0 {
t.Fatal("got incorrect result")
}
}
5 changes: 4 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ var (
noast = flag.Bool("noast", false, "disable AST")
strict = flag.Bool("strict", false, "treat compiler warnings as errors")
filename = flag.String("output", "", "specify name of output file")
ignorecase = flag.Bool("ignorecase",false,"generate ast for all rules, not just ones that start with a capital letter")
)

func main() {
Expand All @@ -39,8 +40,10 @@ func main() {
if err != nil {
log.Fatal(err)
}
t := tree.New(*inline, *_switch, *noast)
t.IgnoreCase = *ignorecase // we do this to avoid having to change the function signature

p := &Peg{Tree: tree.New(*inline, *_switch, *noast), Buffer: string(buffer)}
p := &Peg{Tree:t, Buffer: string(buffer)}
p.Init(Pretty(true), Size(1<<15))
if err := p.Parse(); err != nil {
log.Fatal(err)
Expand Down
10 changes: 10 additions & 0 deletions tree/peg.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.