Ejemplo n.º 1
0
func base64_parser() hammer.Parser {
	digit := hammer.ChRange('0', '9')
	alpha := hammer.Choice(
		hammer.ChRange('A', 'Z'),
		hammer.ChRange('a', 'z'),
	)

	plus := hammer.Ch('+')
	slash := hammer.Ch('/')
	equals := hammer.Ch('=')

	bsfdig := hammer.Choice(alpha, digit, plus, slash)
	bsfdig_4bit := hammer.In([]byte("AEIMQUYcgkosw048"))
	bsfdig_2bit := hammer.In([]byte("AQgw"))

	base64_3 := hammer.RepeatN(bsfdig, 4)
	base64_2 := hammer.Sequence(bsfdig, bsfdig, bsfdig_4bit, equals)
	base64_1 := hammer.Sequence(bsfdig, bsfdig_2bit, equals, equals)

	base64 := hammer.Sequence(
		hammer.Many(base64_3),
		hammer.Optional(
			hammer.Choice(base64_2, base64_1),
		),
	)

	return base64
}
Ejemplo n.º 2
0
func init() {
	end := hammer.Ch('e')
	colon := hammer.Ch(':')
	neg := hammer.Ch('-')

	digits := hammer.Many1(hammer.ChRange('0', '9'))

	uint_10 := hammer.Action(digits, func(token ast.Token) (ast.Token, bool) {
		numstr := charSequenceString(token.Value.([]ast.Token))

		num, err := strconv.ParseUint(numstr, 10, 64)
		if err != nil {
			return token, false
		}

		token.Value = num
		return token, true
	})

	int_10 := hammer.Action(hammer.Sequence(hammer.Optional(neg), digits), func(token ast.Token) (ast.Token, bool) {
		tokens := token.Value.([]ast.Token)
		neg, digits := tokens[0], tokens[1]
		numstr := charSequenceString(digits.Value.([]ast.Token))

		num, err := strconv.ParseInt(numstr, 10, 64)
		if err != nil {
			return token, false
		}

		if neg.Value != ast.None {
			num *= -1
		}

		token.Value = num
		return token, true
	})

	b_string := hammer.LengthValue(hammer.Left(uint_10, colon), hammer.Uint8())
	b_int := hammer.Sequence(hammer.Ch('i'), int_10, end)
	b_list := hammer.Indirect()
	b_dict := hammer.Indirect()

	anyType := hammer.Choice(b_int, b_string, b_list, b_dict)

	hammer.BindIndirect(b_list, hammer.Sequence(
		hammer.Ch('l'),
		hammer.Many(anyType),
		end,
	))
	hammer.BindIndirect(b_dict, hammer.Sequence(
		hammer.Ch('d'),
		hammer.Many(hammer.Sequence(b_string, anyType)),
		end,
	))

	bencode = anyType
}
Ejemplo n.º 3
0
func main() {
	base64Parser := base64_parser()
	documentParser := hammer.Sequence(
		hammer.Whitespace(base64Parser),
		hammer.Whitespace(hammer.End()),
	)

	input := []byte("aGk=") // "hi"
	ast, err := hammer.Parse(documentParser, input)
	if err != nil {
		log.Println(err)
	}

	fmt.Printf("%#v\n", ast)
}
Ejemplo n.º 4
0
func main() {
	jsonParser := jsonParser_init()
	documentParser := hammer.Sequence(
		hammer.Whitespace(jsonParser),
		hammer.Whitespace(hammer.End()),
	)

	input := []byte("{\"name\":\"foo\",\"num\":100,\"balance\":1000.21,\"is_vip\":true,\"nickname\":null}")

	ast, err := hammer.Parse(documentParser, input)
	if err != nil {
		log.Println(err)
	}

	fmt.Printf("%#v\n", ast)
}
Ejemplo n.º 5
0
func jsonParser_init() hammer.Parser {
	// string
	jsonString := hammer.Sequence(
		hammer.Ch('"'),
		hammer.Many1(
			hammer.Choice(
				hammer.ChRange('\x20', '\x21'), // skip "
				hammer.ChRange('\x23', '\x2E'), // skip /
				hammer.ChRange('\x30', '\x5B'), // skip \
				hammer.ChRange('\x5D', '\x7E'), // skip DEL
				hammer.Sequence(hammer.Ch('\\'), hammer.Ch('"')),
				hammer.Sequence(hammer.Ch('\\'), hammer.Ch('\\')),
				hammer.Sequence(hammer.Ch('\\'), hammer.Ch('/')),
				hammer.Sequence(hammer.Ch('\\'), hammer.Ch('b')),
				hammer.Sequence(hammer.Ch('\\'), hammer.Ch('f')),
				hammer.Sequence(hammer.Ch('\\'), hammer.Ch('n')),
				hammer.Sequence(hammer.Ch('\\'), hammer.Ch('r')),
				hammer.Sequence(hammer.Ch('\\'), hammer.Ch('t')),
				hammer.Sequence(hammer.Ch('\\'), hammer.Ch('u')),
			),
		),
		hammer.Ch('"'),
	)

	// number
	jsonNumber := hammer.Sequence(
		hammer.Optional(hammer.Ch('-')),
		hammer.Choice(
			hammer.Ch('0'),
			hammer.Sequence(
				hammer.ChRange('1', '9'),
				hammer.Many1(hammer.ChRange('0', '9')),
			),
		),
		hammer.Optional(hammer.Sequence(
			hammer.Ch('.'),
			hammer.Many1(hammer.ChRange(0, 9)),
		)),
		hammer.Optional(hammer.Sequence(
			hammer.Choice(hammer.Ch('e'), hammer.Ch('E')),
			hammer.Optional(hammer.Choice(hammer.Ch('+'), hammer.Ch('-'))),
			hammer.Many1(hammer.ChRange(0, 9)),
		)),
	)

	// indirects for use in value
	jsonArray := hammer.Indirect()
	jsonObject := hammer.Indirect()

	// value
	jsonValue := hammer.Choice(
		jsonString,
		jsonNumber,
		jsonObject,
		jsonArray,
		hammer.Token([]byte("true")),
		hammer.Token([]byte("false")),
		hammer.Token([]byte("null")),
	)

	// array
	hammer.BindIndirect(jsonArray,
		hammer.Sequence(
			hammer.Ch('['),
			hammer.SepBy1(jsonValue, hammer.Ch(',')),
			hammer.Ch(']'),
		),
	)

	// object
	hammer.BindIndirect(jsonObject,
		hammer.Sequence(
			hammer.Ch('{'),
			jsonString,
			hammer.Ch(':'),
			jsonValue,
			hammer.Ch('}'),
		),
	)

	return jsonObject
}