Skip to content

Instantly share code, notes, and snippets.

@46bit
Created January 5, 2018 13:19
Show Gist options
  • Select an option

  • Save 46bit/a21f03c51657a5b4d4adf8f4c59623b3 to your computer and use it in GitHub Desktop.

Select an option

Save 46bit/a21f03c51657a5b4d4adf8f4c59623b3 to your computer and use it in GitHub Desktop.
// a = 1;
// b = 2;
// c(i) = i * 5;
// d = c(a) / c(b);
// non_whitespace_and_not_eq|whitespace?|eq|whitespace?|expression
// not_eq!("!")
// take_until_either("=")
// named!(tag_length_value<(u8, &[u8])>,
// do_parse!(
// tag!( &[ 42u8 ][..] ) >>
// length: be_u8 >>
// bytes: take!(length) >>
// (length, bytes)
// )
// );
#![feature(slice_patterns)]
#[macro_use]
extern crate nom;
//use std::io::{stdin, Read};
use std::{num, string};
use nom::{is_space, is_digit};
#[derive(Debug, Clone)]
enum Statement {
Assignment(Assignment)
}
#[derive(Debug, Clone)]
struct Assignment {
name: String,
expression: Expression
}
fn new_assignment(name: &[u8], expression: Expression) -> Assignment {
Assignment{
name: to_str(name).unwrap(),
expression: expression
}
}
#[derive(Debug, Clone)]
struct Expression {
first_operand: Operand,
operations: Vec<(Operator, Operand)>
}
fn new_expression((first_operand, operations): (Operand, Vec<(Operator, Operand)>)) -> Expression {
Expression {
first_operand: first_operand,
operations: operations
}
}
#[derive(Debug, Clone, Copy)]
enum Operator {
Add,
Subtract,
Multiply,
Divide
}
#[derive(Debug, Clone)]
enum Operand {
U64(u64),
FunctionApplication(String, Vec<Expression>)
}
fn to_str(u8s: &[u8]) -> Result<String, string::FromUtf8Error> {
String::from_utf8(u8s.to_vec())
}
fn to_u64(u8s: &[u8]) -> Result<u64, num::ParseIntError> {
to_str(u8s).unwrap().parse()
}
named!(statements<&[u8], Vec<Statement>>,
many0!(call!(statement)));
named!(statement<&[u8], Statement>,
alt_complete!(
map!(assignment, Statement::Assignment)));
named!(assignment<&[u8], Assignment>,
do_parse!(
name: call!(variable_name) >>
ws!(tag!("=")) >>
expression: call!(expression) >>
ws!(tag!(";")) >>
(new_assignment(name, expression))));
named!(variable_name<&[u8], &[u8]>,
take_till!(|b: u8| is_space(b) || b == b'='));
named!(function_name<&[u8], &[u8]>,
take_till!(|b: u8| is_space(b) || b == b'('));
named!(expressions<&[u8], Vec<Expression>>,
separated_list!(tag!(","), call!(expression)));
named!(expression<&[u8], Expression>,
map!(
pair!(
call!(operand),
many0!(pair!(
ws!(call!(operator)),
call!(operand)))),
new_expression));
named!(operator<&[u8], Operator>,
map!(one_of!("+-*/"), |o| match o {
'+' => Operator::Add,
'-' => Operator::Subtract,
'*' => Operator::Multiply,
'/' => Operator::Divide,
_ => unreachable!()
}));
named!(operand<&[u8], Operand>,
alt_complete!(
map!(u64, Operand::U64) |
map!(function_application, |(a, b)| Operand::FunctionApplication(a, b))));
named!(u64<&[u8], u64>,
map!(take_while1!(is_digit), |i| to_u64(i).unwrap()));
named!(function_application<&[u8], (String, Vec<Expression>)>,
do_parse!(
name: call!(function_name) >>
tag!("(") >>
expressions: call!(expressions) >>
tag!(")") >>
(to_str(name).unwrap(), expressions)));
named!(end<&[u8], &[u8]>,
alt_complete!(tag!("a") | eof!()));
fn main() {
println!("end {:?}", end(b""));
println!("name {:?}", variable_name(b"a"));
println!("name {:?}", variable_name(b"abc"));
println!("name {:?}", variable_name(b"abc "));
println!("name {:?}", variable_name(b"abc="));
println!("name {:?}", variable_name(b"abc ="));
println!("expression {:?}", expression(b"123456"));
println!("expression {:?}", expression(b"1;"));
println!("expression {:?}", expression(b"123;"));
println!("expression {:?}", expression(b"1+4+7;"));
println!("expression {:?}", expression(b"1 + 4 + 7;"));
println!("expression {:?}", expression(b"3 + 6 + 9 ;"));
println!("expression {:?}", expression(b"1 + 3 * 6 / 9;"));
println!("assignment {:?}", assignment(b"a=1;"));
println!("assignment {:?}", assignment(b"a = 1;"));
println!("assignment {:?}", assignment(b"a = 1 + 3 * 6 / 9;"));
println!("statement {:?}", statement(b"a = 1 + 3 * 6 / 9;"));
println!("statements {:?}", statements(b"a = 1 + 3 * 6 / 9;\nb = 5 * 3;"));
println!("statements {:?}", statements(b"a = 1 + 3 * 6 / 9;\nb = 5 * "));
println!("statements {:?}", statements(b"a = 1 + 3 * 6 / 9;\nb = 5 * a(5 * 3) + 5;"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment