Created
April 1, 2009 01:52
-
-
Save knowtheory/88498 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # -*- coding: utf-8 -*- | |
| require 'treetop' | |
| #require 'lib/measures'; require 'metric/metric' | |
| module TreetopExt | |
| def tokens(options={}) | |
| if nonterminal? | |
| return elements.map{ |e| e.tokens(options) }.flatten.compact | |
| elsif input[interval].empty? or input[interval] =~ /\s+/ | |
| return nil | |
| else | |
| return input[interval] | |
| end | |
| end | |
| def flatten | |
| input[interval] | |
| end | |
| def normalize(options={}) | |
| tokens(options.merge({:normalize=>true,:distribute=>true,:simplify=>true})) | |
| end | |
| def factor(options={}) | |
| normalize(options.merge(:factor=>true)) | |
| end | |
| end | |
| class Treetop::Runtime::SyntaxNode | |
| include TreetopExt | |
| end | |
| module Definition | |
| include Treetop::Runtime | |
| class DefinitionNode < ::Treetop::Runtime::SyntaxNode; end | |
| class ExponentNode < DefinitionNode | |
| def value | |
| basic_quantity.input[basic_quantity.interval] | |
| end | |
| end | |
| class OpArgNode < DefinitionNode | |
| def tokens(options={}) | |
| #pp options | |
| op = operator.tokens | |
| if options[:normalize] and op =~ /\/|÷/ | |
| exp = options[:exponent] | |
| exp ||= 1 | |
| ["*"] + [expression.tokens(options.merge({:exponent=>-1*exp}))].flatten.compact | |
| else | |
| super | |
| end | |
| end | |
| end | |
| class ExpressionNode < DefinitionNode | |
| end | |
| class QuantityNode < DefinitionNode | |
| attr_accessor :exponent | |
| def initialize(input,interval,elements) | |
| super | |
| unless (element = elements.select{ |e| e.is_a? Definition::ExponentNode }.first).nil? | |
| exp = element.basic_quantity | |
| @exponent = exp.input[exp.interval].to_f | |
| else | |
| @exponent ||= 1 | |
| end | |
| end | |
| def tokens(options={}) | |
| #pp options | |
| exp = exponent | |
| unless options[:exponent].nil? | |
| exp = exponent * options[:exponent] | |
| end | |
| case | |
| when (nonterminal? and options[:distribute]) | |
| value.tokens(options.merge(:exponent => exp)) | |
| when nonterminal? | |
| super(options.merge(:exponent => exp)) | |
| else | |
| input[interval] | |
| end | |
| end | |
| end | |
| class ParentheticalNode < QuantityNode | |
| def tokens(options={}) | |
| #pp options | |
| exp = exponent | |
| unless options[:exponent].nil? | |
| exp = exponent * options[:exponent] | |
| end | |
| children = expression.tokens(options.merge(:exponent => exp)) | |
| case | |
| when (options[:simplify] and parent.parent.is_a? ExpressionNode) | |
| children.flatten | |
| when (options[:simplify] and not (children.include?("-") or children.include?("+") or options[:exponent] != 1)) | |
| children.flatten | |
| else | |
| ["(", children, ")"].flatten | |
| end | |
| end | |
| end | |
| class TextNode < QuantityNode | |
| def tokens(options={}) | |
| token_store = input[interval] | |
| if options[:distribute] and options[:exponent] != 1 | |
| return [token_store + "^" + "#{exponent * options[:exponent]}"].flatten | |
| else | |
| return token_store | |
| end | |
| end | |
| def factored_definition | |
| Ministry.identify(measure.input[measure.interval]).factored_definition | |
| end | |
| end | |
| class NumericNode < QuantityNode | |
| def tokens(options={}) | |
| #puts options | |
| if options[:distribute] and options[:exponent] != 1 | |
| [input[interval], "^", "#{exponent * options[:exponent]}"].flatten | |
| else | |
| input[interval] | |
| end | |
| end | |
| end | |
| end | |
| class DefinitionParser < Treetop::Runtime::CompiledParser | |
| include Definition | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| grammar Definition | |
| rule expression | |
| (quantity op_and_arg) <ExpressionNode> / quantity | |
| end | |
| rule op_and_arg | |
| operator expression <OpArgNode> | |
| end | |
| rule operator | |
| "+" <OperatorNode> / | |
| "-" <OperatorNode> / | |
| "*" <OperatorNode> / | |
| "/" <OperatorNode> / | |
| "×" <OperatorNode> / | |
| "÷" <OperatorNode> | |
| end | |
| rule quantity | |
| [\s]* value:(parenthetical / basic_quantity) [\s]* (exponentiation)? [\s]* <QuantityNode> | |
| end | |
| rule parenthetical | |
| "(" expression ")" <ParentheticalNode> | |
| end | |
| rule exponentiation | |
| operator:("^" / "**") [\s]* basic_quantity <ExponentNode> | |
| end | |
| rule basic_quantity | |
| (text / number) | |
| end | |
| rule number | |
| "-"? [\s]* [0-9]+ "."? [0-9]* <NumericNode> | |
| end | |
| rule text | |
| ( modifier:(character+) "." )? measure:character+ <TextNode> | |
| #([αβγδϛϝζηθικλμνξοπϙρσςτυφχψωΓΔϚΘΛΞΠϘΣΥΦΨΩΩµa-zA-Z]+ ".")? [αβγδϛϝζηθικλμνξοπϙρσςτυφχψωΓΔϚΘΛΞΠϘΣΥΦΨΩΩµA-Za-z]+ <TextNode> # outlawing underscores. just add it to the character class to renable. | |
| end | |
| rule character | |
| [A-Za-z]/"∂"/"∆"/"α"/"β"/"γ"/"δ"/"ϛ"/"ϝ"/"ζ"/"η"/"θ"/"ι"/"κ"/"λ"/"μ"/"ν"/"ξ"/"ο"/"π"/"ϙ"/"ρ"/"σ"/"ς"/"τ"/"υ"/"φ"/"χ"/"ψ"/"ω"/"Γ"/"Δ"/'Ϛ'/'Θ'/"Λ"/"Ξ"/"Π"/"Ϙ"/"Σ"/"Υ"/"Φ"/"Ψ"/"Ω"/"Ω"/"µ"/"°" | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment