Specification
$flags: 'OPTIONAL_WHITESPACE'
Token:
Identifier: '[A-Za-z][A-Za-z0-9_]*'
Expression:
Number: '\d+(\.\d+)?'
Variable: '${Identifier}(?!\s*\()'
FunctionCall:
$fields: { name: Token::Identifier, arguments: 'Expression[]' }
$patterns: '#{name}\( (#{arguments}(, #{arguments})*)? \)'
Grouped:
$fields: { value: Expression }
$patterns: '\( #{value} \)'
Power:
$fields: { base: Expression, exponent: Expression }
$patterns: '#{base} \^ #{exponent}'
Product:
$types:
MultiplicativeOperator: '\*|/'
Factor:
$fields: { operator: MultiplicativeOperator, value: Expression }
$patterns: '#{operator} #{value}'
$fields: { first: Expression, factors: 'Factor[]' }
$patterns: '#{first}( #{factors})+'
Sum:
$types:
AdditiveOperator: '[+-]'
Term:
$fields: { operator: AdditiveOperator, value: Expression }
$patterns: '#{operator} #{value}'
$fields: { first: Expression, terms: 'Term[]' }
$patterns: '#{first}( #{terms})+'
Statement:
Assignment:
$fields: { target: Variable, value: Expression }
$patterns: '#{target} = #{value}'
FunctionDefinition:
$fields: { target: FunctionCall, value: Expression }
$patterns: '#{target} = #{value}'
Comparison:
$types: { ComparisonOperator: '>=|<=|<>|!=|=|>|<' }
$fields: { left: Expression, operator: ComparisonOperator, right: Expression }
$patterns: '#{left} #{operator} #{right}'Sample input
f(x) = (x + 3)^2
y = x^2 + pi/2*x - 4
sin(x) >= cos(y)
result = min(avg(a, b), max(c, d))
area = pi * r^2
Result
[
{
"type": "Statement::FunctionDefinition",
"text": "f(x) = (x + 3)^2",
"start": 0,
"end": 16,
"fields": [
{
"type": "Expression::FunctionCall",
"field": "target",
"text": "f(x)",
"start": 0,
"end": 4,
"fields": [
{
"type": "Token::Identifier",
"field": "name",
"text": "f",
"start": 0,
"end": 1
},
{
"type": "Expression[]",
"field": "arguments",
"text": "x",
"start": 2,
"end": 3,
"items": [
{
"type": "Expression::Variable",
"text": "x",
"start": 2,
"end": 3
}
]
}
]
},
{
"type": "Expression::Power",
"field": "value",
"text": "(x + 3)^2",
"start": 7,
"end": 16,
"fields": [
{
"type": "Expression::Grouped",
"field": "base",
"text": "(x + 3)",
"start": 7,
"end": 14,
"fields": [
{
"type": "Expression::Sum",
"field": "value",
"text": "x + 3",
"start": 8,
"end": 13,
"fields": [
{
"type": "Expression::Variable",
"field": "first",
"text": "x",
"start": 8,
"end": 9
},
{
"type": "Term[]",
"field": "terms",
"text": "+ 3",
"start": 10,
"end": 13,
"items": [
{
"type": "Term",
"text": "+ 3",
"start": 10,
"end": 13,
"fields": [
{
"type": "AdditiveOperator",
"field": "operator",
"text": "+",
"start": 10,
"end": 11
},
{
"type": "Expression::Number",
"field": "value",
"text": "3",
"start": 12,
"end": 13
}
]
}
]
}
]
}
]
},
{
"type": "Expression::Number",
"field": "exponent",
"text": "2",
"start": 15,
"end": 16
}
]
}
]
},
{
"type": "Statement::Assignment",
"text": "y = x^2 + pi/2*x - 4",
"start": 17,
"end": 37,
"fields": [
{
"type": "Expression::Variable",
"field": "target",
"text": "y",
"start": 17,
"end": 18
},
{
"type": "Expression::Sum",
"field": "value",
"text": "x^2 + pi/2*x - 4",
"start": 21,
"end": 37,
"fields": [
{
"type": "Expression::Power",
"field": "first",
"text": "x^2",
"start": 21,
"end": 24,
"fields": [
{
"type": "Expression::Variable",
"field": "base",
"text": "x",
"start": 21,
"end": 22
},
{
"type": "Expression::Number",
"field": "exponent",
"text": "2",
"start": 23,
"end": 24
}
]
},
{
"type": "Term[]",
"field": "terms",
"text": "+ pi/2*x - 4",
"start": 25,
"end": 37,
"items": [
{
"type": "Term",
"text": "+ pi/2*x",
"start": 25,
"end": 33,
"fields": [
{
"type": "AdditiveOperator",
"field": "operator",
"text": "+",
"start": 25,
"end": 26
},
{
"type": "Expression::Product",
"field": "value",
"text": "pi/2*x",
"start": 27,
"end": 33,
"fields": [
{
"type": "Expression::Variable",
"field": "first",
"text": "pi",
"start": 27,
"end": 29
},
{
"type": "Factor[]",
"field": "factors",
"text": "/2*x",
"start": 29,
"end": 33,
"items": [
{
"type": "Factor",
"text": "/2",
"start": 29,
"end": 31,
"fields": [
{
"type": "MultiplicativeOperator",
"field": "operator",
"text": "/",
"start": 29,
"end": 30
},
{
"type": "Expression::Number",
"field": "value",
"text": "2",
"start": 30,
"end": 31
}
]
},
{
"type": "Factor",
"text": "*x",
"start": 31,
"end": 33,
"fields": [
{
"type": "MultiplicativeOperator",
"field": "operator",
"text": "*",
"start": 31,
"end": 32
},
{
"type": "Expression::Variable",
"field": "value",
"text": "x",
"start": 32,
"end": 33
}
]
}
]
}
]
}
]
},
{
"type": "Term",
"text": "- 4",
"start": 34,
"end": 37,
"fields": [
{
"type": "AdditiveOperator",
"field": "operator",
"text": "-",
"start": 34,
"end": 35
},
{
"type": "Expression::Number",
"field": "value",
"text": "4",
"start": 36,
"end": 37
}
]
}
]
}
]
}
]
},
{
"type": "Statement::Comparison",
"text": "sin(x) >= cos(y)",
"start": 38,
"end": 54,
"fields": [
{
"type": "Expression::FunctionCall",
"field": "left",
"text": "sin(x)",
"start": 38,
"end": 44,
"fields": [
{
"type": "Token::Identifier",
"field": "name",
"text": "sin",
"start": 38,
"end": 41
},
{
"type": "Expression[]",
"field": "arguments",
"text": "x",
"start": 42,
"end": 43,
"items": [
{
"type": "Expression::Variable",
"text": "x",
"start": 42,
"end": 43
}
]
}
]
},
{
"type": "ComparisonOperator",
"field": "operator",
"text": ">=",
"start": 45,
"end": 47
},
{
"type": "Expression::FunctionCall",
"field": "right",
"text": "cos(y)",
"start": 48,
"end": 54,
"fields": [
{
"type": "Token::Identifier",
"field": "name",
"text": "cos",
"start": 48,
"end": 51
},
{
"type": "Expression[]",
"field": "arguments",
"text": "y",
"start": 52,
"end": 53,
"items": [
{
"type": "Expression::Variable",
"text": "y",
"start": 52,
"end": 53
}
]
}
]
}
]
},
{
"type": "Statement::Assignment",
"text": "result = min(avg(a, b), max(c, d))",
"start": 55,
"end": 89,
"fields": [
{
"type": "Expression::Variable",
"field": "target",
"text": "result",
"start": 55,
"end": 61
},
{
"type": "Expression::FunctionCall",
"field": "value",
"text": "min(avg(a, b), max(c, d))",
"start": 64,
"end": 89,
"fields": [
{
"type": "Token::Identifier",
"field": "name",
"text": "min",
"start": 64,
"end": 67
},
{
"type": "Expression[]",
"field": "arguments",
"text": "avg(a, b), max(c, d)",
"start": 68,
"end": 88,
"items": [
{
"type": "Expression::FunctionCall",
"text": "avg(a, b)",
"start": 68,
"end": 77,
"fields": [
{
"type": "Token::Identifier",
"field": "name",
"text": "avg",
"start": 68,
"end": 71
},
{
"type": "Expression[]",
"field": "arguments",
"text": "a, b",
"start": 72,
"end": 76,
"items": [
{
"type": "Expression::Variable",
"text": "a",
"start": 72,
"end": 73
},
{
"type": "Expression::Variable",
"text": "b",
"start": 75,
"end": 76
}
]
}
]
},
{
"type": "Expression::FunctionCall",
"text": "max(c, d)",
"start": 79,
"end": 88,
"fields": [
{
"type": "Token::Identifier",
"field": "name",
"text": "max",
"start": 79,
"end": 82
},
{
"type": "Expression[]",
"field": "arguments",
"text": "c, d",
"start": 83,
"end": 87,
"items": [
{
"type": "Expression::Variable",
"text": "c",
"start": 83,
"end": 84
},
{
"type": "Expression::Variable",
"text": "d",
"start": 86,
"end": 87
}
]
}
]
}
]
}
]
}
]
},
{
"type": "Statement::Assignment",
"text": "area = pi * r^2",
"start": 90,
"end": 105,
"fields": [
{
"type": "Expression::Variable",
"field": "target",
"text": "area",
"start": 90,
"end": 94
},
{
"type": "Expression::Product",
"field": "value",
"text": "pi * r^2",
"start": 97,
"end": 105,
"fields": [
{
"type": "Expression::Variable",
"field": "first",
"text": "pi",
"start": 97,
"end": 99
},
{
"type": "Factor[]",
"field": "factors",
"text": "* r^2",
"start": 100,
"end": 105,
"items": [
{
"type": "Factor",
"text": "* r^2",
"start": 100,
"end": 105,
"fields": [
{
"type": "MultiplicativeOperator",
"field": "operator",
"text": "*",
"start": 100,
"end": 101
},
{
"type": "Expression::Power",
"field": "value",
"text": "r^2",
"start": 102,
"end": 105,
"fields": [
{
"type": "Expression::Variable",
"field": "base",
"text": "r",
"start": 102,
"end": 103
},
{
"type": "Expression::Number",
"field": "exponent",
"text": "2",
"start": 104,
"end": 105
}
]
}
]
}
]
}
]
}
]
}
]Notes
# Mathematical Expressions
Recognize small expression statements: assignments, comparisons, calls, variables, and arithmetic.
## Notice
- `Expression` is the parent type for values.
- Concrete forms include numbers, variables, calls, sums, products, and powers.
- `Sum` and `Product` keep the first value separate from repeated operator/value terms.
- `Statement` separates assignment, function definition, and comparison.
- Fields such as `target`, `value`, `left`, `right`, and `operator` keep the result inspectable.
Try adding `sqrt(x^2 + y^2) >= 10`.