gpt4 book ai didi

ruby - 树顶 bool 逻辑运算

转载 作者:数据小太阳 更新时间:2023-10-29 07:55:26 24 4
gpt4 key购买 nike

我正在实现具有语法的 DSL:

"[keyword] or ([other keyword] and not [one more keyword])"

每个关键字都将转换为 bool 值(true, false),然后使用运算符and, or, not 进行计算

我当前的语法规则仅匹配字符串 [keyword] 或 [other keyword] 并且在 stings [keyword] 或 [other keyword] 或 [one more keyword] 上失败

如何编写匹配任意数量的 orand 结构的语法?

语法:

grammar Sexp

rule expression
keyword operand keyword <ExpressionLiteral>
end

rule operand
or / and <OperandLiteral>
end

rule or
'or' <OrLiteral>
end

rule and
'and' <AndLiteral>
end

rule keyword
space '[' ( '\[' / !']' . )* ']' space <KeywordLiteral>
end

rule space
' '*
end
end

更新

解析器类

class Parser
require 'treetop'
base_path = File.expand_path(File.dirname(__FILE__))
require File.join(base_path, 'node_extensions.rb')
Treetop.load(File.join(base_path, 'sexp_parser.treetop'))

def self.parse(data)
if data.respond_to? :read
data = data.read
end

parser =SexpParser.new
ast = parser.parse data

if ast
#self.clean_tree(ast)
return ast
else
parser.failure_reason =~ /^(Expected .+) after/m
puts "#{$1.gsub("\n", '$NEWLINE')}:"
puts data.lines.to_a[parser.failure_line - 1]
puts "#{'~' * (parser.failure_column - 1)}^"
end
end
private
def self.clean_tree(root_node)
return if(root_node.elements.nil?)
root_node.elements.delete_if{|node| node.class.name == "Treetop::Runtime::SyntaxNode" }
root_node.elements.each {|node| self.clean_tree(node) }
end
end

tree = Parser.parse('[keyword] or [other keyword] or [this]')
p tree
p tree.to_array

节点扩展

module Sexp
class KeywordLiteral < Treetop::Runtime::SyntaxNode
def to_array
self.text_value.gsub(/[\s\[\]]+/, '')
end
end

class OrLiteral < Treetop::Runtime::SyntaxNode
def to_array
self.text_value
end
end

class AndLiteral < Treetop::Runtime::SyntaxNode
def to_array
self.text_value
end
end

class OperandLiteral < Treetop::Runtime::SyntaxNode
def to_array
self.elements.map{|e| e.to_array}
end
end

class ExpressionLiteral < Treetop::Runtime::SyntaxNode
def to_array
self.elements.map{|e| e.to_array}.join(' ')
end
end
end

最佳答案

好的,谢谢你的澄清。在 Ruby 中,“false and true or true”为真,因为“and”首先求值(它具有更高的优先级)。要对此进行解析,您需要一个用于“或”列表(析取)的规则,它调用另一个用于“和”列表(连词)的规则。像这样:

rule expression
s disjunction s
{ def value; disjunction.value; end }
end

rule disjunction
conjunction tail:(or s conjunction s)*
{ def value
tail.elements.inject(conjunction.value) do |r, e|
r or e.conjunction.value
end
end
}
end

rule conjunction
primitive tail:(and s primitive s)*
{ def value
tail.elements.inject(primitive.value) do |r, e|
r and e.primitive.value
end
end
}
end

rule primitive
'(' expression ')' s { def value; expression.value; end }
/
not expression s { def value; not expression.value; end }
/
symbol s { def value; symbol.value; end }
end

rule or
'or' !symbolchar s
end

rule and
'and' !symbolchar s
end

rule not
'not' !symbolchar s
end

rule symbol
text:([[:alpha:]_] symbolchar*) s
{ def value
lookup_value(text.text_value)
end
}
end

rule symbolchar
[[:alnum:]_]
end

rule s # Optional space
S?
end

rule S # Mandatory space
[ \t\n\r]*
end

注意一些事情:

  • 关键字不得紧跟符号字符。我为此使用了负前瞻。
  • 最上面的规则使用前导空格,然后几乎每个规则都使用后面的空格(这是我的政策)。您应该使用最小和最大空白测试您的语法。
  • 不需要像您那样在每个规则上都使用语法节点类。
  • 您可以看到如何继续加法、乘法等的模式
  • 我给出了一些计算表达式的代码草图。请使用更漂亮的东西!

关于ruby - 树顶 bool 逻辑运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32373050/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com