我目前正在使用Ruby编写Ruby解析器,更准确地说是Parslet,因为我认为它比Treetop或Citrus更容易使用.我使用官方规范创建我的规则,但有一些我不能写的语句,因为它们"排除"了一些语法,我不知道怎么做......嗯,这里有一个例子供你理解. ..
这是一个基本规则:
foo::=
any-character+ BUT NOT (foo* escape_character barbar*)
# Knowing that (foo* escape_character barbar*) is included in any-character
Run Code Online (Sandbox Code Playgroud)
我怎么能用Parslet翻译呢?也许是缺席?/现在?东西 ?
非常感谢,希望有人有个主意....
祝你今天愉快!
编辑:我试过你说的,所以这是我使用parslet翻译成Ruby语言:
rule(:line_comment){(source_character.repeat >> line_terminator >> source_character.repeat).absent? >> source_character.repeat(1)}
Run Code Online (Sandbox Code Playgroud)
但是,它似乎不起作用(parens中的序列).我做了一些测试,并得出结论,我的parens中写的是错误的.
这是一个非常简单的例子,让我们考虑以下规则:
# Parslet rules
rule(:source_character) {any}
rule(:line_terminator){ str("\n") >> str("\r").maybe }
rule(:not){source_character.repeat >> line_terminator }
# Which looks like what I try to "detect" up there
Run Code Online (Sandbox Code Playgroud)
我这些规则与这些代码:
# Code to test :
code = "test
"
Run Code Online (Sandbox Code Playgroud)
但我明白了:
无法匹配第2行char 1处的序列(SOURCE_CHARACTER {0,} LINE_TERMINATOR).
- Failed to match sequence (SOURCE_CHARACTER{0, } LINE_TERMINATOR) at line 2 char 1.- 无法匹配第2行char 1处的序列('''?).` - 第2行的输入过早结束char 1. nil
如果这个序列不起作用,那么我的"完整"规则将无法工作......如果有人有想法,那就太好了.
谢谢 !
您可以执行以下操作:
rule(:word) { match['^")(\\s'].repeat(1) } # normal word
rule(:op) { str('AND') | str('OR') | str('NOT') }
rule(:keyword) { str('all:') | str('any:') }
rule(:searchterm) { keyword.absent? >> op.absent? >> word }
Run Code Online (Sandbox Code Playgroud)
在这种情况下,absent?会先行检查以确保下一个标记不是关键字;如果不是,则检查以确保它不是运算符;如果不是,最后看看它是否有效word。
一个等效的规则是:
rule(:searchterm) { (keyword | op).absent? >> word }
Run Code Online (Sandbox Code Playgroud)
小智 5
Parslet匹配本质上是贪婪的.这意味着当你重复这样的事情时
foo.repeat
Run Code Online (Sandbox Code Playgroud)
parslet将匹配foo,直到失败.如果foo是
rule(:foo) { any }
Run Code Online (Sandbox Code Playgroud)
你会在失败的道路上,因为any.repeat总是匹配文档的其余部分!
您正在寻找的是类似examples/string_parser.rb(parslet源代码树)中的字符串匹配器:
rule :string do
str('"') >>
(
(str('\\') >> any) |
(str('"').absent? >> any)
).repeat.as(:string) >>
str('"')
end
Run Code Online (Sandbox Code Playgroud)
这说的是:'匹配',然后匹配反斜杠后跟任何字符,或匹配任何其他字符,只要它不是终止"."
所以.absent?实际上是一种从下面的匹配中排除事物的方法:
str('foo').absent? >> (str('foo') | str('bar'))
Run Code Online (Sandbox Code Playgroud)
只会匹配'酒吧'.如果您了解这一点,我认为您将能够解决您的困难.虽然那些不会是你去Ruby解析器的最后一个...
| 归档时间: |
|
| 查看次数: |
1133 次 |
| 最近记录: |