我实现DSL其中有语法:树顶布尔逻辑运算
"[keyword] or ([other keyword] and not [one more keyword])"
每个关键字将转变为布尔(true
,false
)值之后,它应该使用运营商and, or, not
我目前的计算语法规则仅匹配字符串[keyword] or [other keyword]
并且在刺激时失败[keyword] or [other keyword] or [one more keyword]
如何编写与匹配的任何ammount的语法,and
建筑?
语法:
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
我的树梢是生锈的,但是如何处理像规则表达;关键字/表达式操作数表达式; end'?或者通过重复而不是递归表达:'rule expression;关键字(操作数关键字)*;结束' –
@JörgWMittag不起作用。 Treetop期望在两个示例中的'operator'的位置空间 – djsmentya
您没有定义您是否期望AND和OR具有更高的优先级。这是计算机语言中的常见用法,AND具有比OR更高的优先级,但您需要确定一种方式或另一种方式,或者您的语法总是需要括号。如果你回答这个问题,我可以回答你的问题。 – cliffordheath