我正在尝试为我的编译器类做一个语法文本校正器。这个想法是:我有一些规则,这是语言所固有的(在我的例子中,葡萄牙语),如“一个有效的短语是主要的动词目标”,如“Ruby很棒”。
好的,首先我必须将输入标记为“Ruby很棒”。所以我有一个文本文件“动词”,有很多动词,一个接一个。然后我有一个文本“形容词”,一个“代词”等等。
我正在尝试使用Ragel来创建一个解析器,但我不知道我该怎么做:
%%{
machine test;
subject = <open-the-subjects-file-and-accept-each-one-of-them>;
verb = <open-the-verbs-file-and-accept-each-one-of-them>;
adjective = <open-the-adjective-file-and-accept-each-one-of-them>;
main = subject verb adjective @ { print "Valid phrase!" } ;
}%%
我看了ANTLR,Lex / Yacc,Ragel等。但找不到一个似乎可以解决这个问题。我能想到的唯一方法是预处理Ragel的输入文件,以便我的程序读取文件并将其内容写入正确的位置。但我也不喜欢这个解决方案。
有谁知道我怎么能这样做?如果没有Ragel没有问题,我只是想解决这个问题。我想使用Ruby或Python,但这也不是必需的。
感谢。
答案 0 :(得分:2)
如果要在编译时读取文件,请将它们格式化为:
subject = \
ruby|\
python|\
c++
然后使用ragel的'include'或'import'语句(我忘了哪个......必须检查手册)来导入它。
如果你想在运行时检查主题列表,也许只需让ragel读3个单词,然后让每个单词都有一个动作。该操作可以读取文件并在运行时查找该单词是否正常。
该操作读取文本文件并比较单词的内容。
%%{
machine test
action startWord {
lastWordStart = p;
}
action checkSubject {
word = input[lastWordStart:p+1]
for possible in open('subjects.txt'):
if possible == word:
fgoto verb
# If we get here do whatever ragel does to go to an error or just raise a python exception
raise Exception("Invalid subject '%s'" % word)
}
action checkVerb { .. exercise for reader .. ;) }
action checkAdjective { .. put adjective checking code here .. }
subject = ws*.(alnum*)>startWord%checkSubject
verb := : ws*.(alnum*)>startWord%checkVerb
adjective := ws*.)alnum*)>startWord%checkAdjective
main := subject;
}%%
答案 1 :(得分:0)
使用野牛,我会手动编写词法分析器,查找预定义词典中的单词。