gpt4 book ai didi

java - DFA 预测和范围

转载 作者:搜寻专家 更新时间:2023-11-01 03:25:20 24 4
gpt4 key购买 nike

从这个语法开始:https://stackoverflow.com/a/14287002/1082002我会实现一个简单的语法来接受和评估这样的简单语言:

{ 
if a==c {
a
if a==b {
b
} else {
c
}
}

}

因此,如果 a==c,它会执行 a 并评估 if a==b,如果为真,它会执行 b 否则 c。真的很简单。

解析器语法和树语法是这些:

TreeEvaluator.g(组合语法生成 AST)

grammar TreeEvaluator;

options {
output = AST;
}

tokens {
CONDBLOCK;
CODEBLOCK;
DEFAULT;
}


compilationUnit : block EOF -> block;

condition : cif elif* celse? -> ^(IF cif elif* celse?);
cif : IF expr block -> ^(CONDBLOCK expr block);
elif : ELIF expr block -> ^(CONDBLOCK expr block);
celse : ELSE block -> ^(DEFAULT block);
expr : ID EQ^ ID;
block : LCUR instruction* RCUR -> ^(CODEBLOCK instruction*);
instruction : ID | condition;

IF : 'if';
ELIF: 'elif';
ELSE: 'else';
LCUR: '{';
RCUR: '}';
EQ : '==';
ID : ('a'..'z'|'A'..'Z')+;
WS : (' '|'\t'|'\f'|'\r'|'\n')+ {skip();};

AstTreeEvaluatorParser.g(树解析器)

tree grammar AstTreeEvaluatorParser;

options {
output = AST;
tokenVocab = TreeEvaluator;
ASTLabelType = CommonTree;
}

@members {
private static final class Evaluation {
boolean matched = false;
boolean done = false;
}

private java.util.HashMap<String, Integer> vars = new java.util.HashMap<String, Integer>();

public void addVar(String name, int value){
vars.put(name, value);
}

}

compilationUnit : block+;

block : ^(CODEBLOCK instruction*);

instruction : ifStat | ID;

ifStat
@init { Evaluation eval = new Evaluation(); }
: ^(IF condition[eval]* defcond[eval]?)
;

condition [Evaluation eval]
: ^(CONDBLOCK exp {if ($exp.value) eval.matched = true;} evalblock[eval])
;

defcond [Evaluation eval]
: ^(DEFAULT {eval.matched = true;} evalblock[eval]) //force a match
;

evalblock [Evaluation eval]
: {eval.matched && !eval.done}? //Only do this when a condition is matched but not finished
block //call the execution code
{eval.done = true;} //evaluation is complete.
| ^(CODEBLOCK .*) //read the code node and continue without executing
;

exp returns [boolean value]
: ^(EQ lhs=ID rhs=ID)
{$value = vars.get($lhs.getText()) == vars.get($rhs.getText());}
;

问题是为预测规则 evalblock 生成的 DFA,这个 DFA 有一个方法 SpecialStateTransition() 引用参数 eval (如规则中所指定),但在生成的 Java 类中,该参数不可见。

我不明白为什么,是否有办法避免这个问题。

最佳答案

你有一个语义谓词(语法 {...}?),它包含对一个值的引用,该值被一个 Action 改变(语法 {...} >).在您的例子中,值是字段 Evaluation.matchedEvaluation.done

您应该完全避免这种情况 - 永远不要¹包括依赖于正在执行的操作的谓词。相反,通过将 action 代码包装在 if (eval.matched && !eval.done) { ... }

中来检查操作中的这些值

¹ 有些人编写的语法以这种方式交互,但我严格避免这种方式,因为可能会出现您所看到的问题以及其他更糟糕的问题。

关于java - DFA 预测和范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15410973/

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