递归下降解析器和嵌套括号

时间:2012-07-09 23:04:31

标签: parsing grammar recursive-descent

我是语法和解析领域的新手。

我正在尝试编写一个递归下降解析器来评估这样的字符串:

((3 == 5 AND 4 == 5)OR(6 == 6))

在我开始处理嵌套括号之前,一切正常。基本上我发现我太早到达目标字符串的末尾。

我认为问题是由于当我遇到像“6”或倒数第二个括号这样的令牌时,我会对其进行评估,然后转移到下一个令牌。我会删除前进到下一个令牌的代码,但后来我不确定我是如何前进的。

我的语法就像这样(“=>”符号是我自己对规则“翻译”的符号):

测试:如果CompoundSentence然后是CompoundSentence | CompoundSentence

CompoundSentence :( CompoundSentence)PCSopt | CompoundSentence Conjunction Sentence |

句子=>

CompoundSentence =(CompoundSentence)PCSopt |句子CSOpt

PCSOpt = ParenConjunction CompoundSentence PCSOpt |小量

CSOpt =连词句子CSOpt |小量

ParenConjunction:和|或

连词:和|或

句子:主语动词前缀

主题:主题中缀值|值=>

主题=价值主体

SubjectOpt =中缀值SubjectOpt |小量

动词:== |!= |> |<

谓词:谓词中缀值|值=>

Predicate = Value PredicateOpt

PredicateOpt =中缀值PredicateOpt |小量

中缀:+, - ,*,/

复合句的代码如下:

    private string CompoundSentence(IEnumerator<Token> ts)
    {
        //  CompoundSentence = ( CompoundSentence ) PCSopt  | Sentence CSOpt

        string sReturnValue = "";

        switch(ts.Current.Category) {

            case "OPENPAREN":
            {
                     //Skip past the open parenthesis
                ts.MoveNext();

                string sCSValue = CompoundSentence(ts);

                if(ts.Current.Category != "CLOSEPAREN") {

                    sReturnValue = "Missing parenthesis at " + ts.Current.OriginalString;
                    return sError;
                }
                else {

                        //Skip past the close parenthesis
                    ts.MoveNext();  
                }

                sReturnValue = PCSOpt(sCSValue, ts);

                break;
            }
            default:
            {
                string sSentenceVal = Sentence(ts);

                    //sSentenceVal is the truth value -- "TRUE" or "FALSE"
                    //of the initial Sentence component
                    //CSOpt will use that value, along with the particular conjunction
                    //and the value of the current token, 
                    //to generate a new truth value.
                sReturnValue = CSOpt(sSentenceVal, ts);

                break;
            }
        }

        return sReturnValue;
    }

正如我所说,我是这个领域的新手,所以我可能不会理解一些非常基础的东西。

如果有人能引导我朝着正确的方向前进,我会非常感激。

3 个答案:

答案 0 :(得分:1)

对于表达式,手工编码的递归下降解析器很容易编码。

查看我的SO answer for how to write recursive descent parsers.

一旦获得了解析器的结构,就可以很容易地计算出一个解析表达式。

答案 1 :(得分:0)

解析的基本约定是:

  1. 在规则开始时,当前令牌应该是规则涵盖的第一个令牌。

  2. 规则应该使用它涵盖的所有令牌。

答案 2 :(得分:0)

我认为它非常微妙,但事实证明这很简单:我的扫描仪没有抓住第二个(可能更高)的近括号。哎哟。

感谢大家的帮助。

艾拉,我会接受你在RDP上提供的详细帮助的答案。