我正在創建甲 CCESS Ç ONTROL 小號特林(或小號 ystem)( ACS)帶有PEG.js的字符串解析器/解釋器。 ACS字符串通常用於公告板系統(BBS)上,以檢查對電路板特定區域的訪問權限。例如,請參閱Renegade's ACS documentation。
例ACS字符串
下面是一些簡單的字符串,他們的英語翻譯說明:
// Has GM123 OR NOT GM456
GM123|!GM456
// Has GM123 OR NOT (GM456 AND GM789) (note: AND is implied in this grammar if not specified)
GM123|!(GM456GM789)
// Has GM123 AND NOT GM456 OR has GM789
GM123!GM456|GM789
// Has GM1 OR (NOT GM2 OR GM3)
GM1|(!GM2|GM3)
我正在努力實現
我想什麼在這裏做的是解析和解釋(或「運行」)ACS字符串,並最終結束最後的噓聲靠。
語法到目前爲止
下面是PEG.js語法我有一些了爲止。請注意,ACS字符串本身比上面的示例(我允許例如GM ['abc','def'])更復雜一點,但我認爲到目前爲止它是相當自我解釋的。
{
function checkAccessSingle(acsName, arg) {
return true;
}
function checkAccessMulti(acsName, args, anyMatch) {
return true;
}
function makeNot(not, x) {
return not ? !x : x;
}
}
start
= acsString
whitespaceChar
= ' '
ws
= whitespaceChar*
lineTerminatorChar
= [\r\n\u2028\u2029]
decimalDigit
= [0-9]
integer
= decimalDigit+ { return parseInt(text(), 10); }
asciiPrintableChar
= [ -~]
singleAsciiStringChar
= !("'") asciiPrintableChar { return text(); }
doubleAsciiStringChar
= !('"') asciiPrintableChar { return text(); }
nonEmptyStringLiteral
= "'" chars:singleAsciiStringChar+ "'" { return chars.join(''); }
/'"' chars:doubleAsciiStringChar+ '"' { return chars.join(''); }
AND
= '&'
OR
= '|'
NOT
= '!'
acsName
= n:([A-Z][A-Z]) { return n.join(''); }
acsArg
= nonEmptyStringLiteral
/integer
acsArgs
= first:acsArg rest:(ws ',' ws a:acsArg { return a; })* {
var args = [ first ];
for(var i = 0; i < rest.length; ++i) {
args.push(rest[i]);
}
return args;
}
singleAcsCheck
= not:NOT? n:acsName a:acsArg* {
return function() {
makeNot(not, checkAccessSingle(n, a));
}
}
/not:NOT? n:acsName '[' a:acsArgs ']' {
return function() {
return makeNot(not, checkAccessMulti(n, a, false));
}
}
/not:NOT? n:acsName '{' a:acsArgs '}' {
return function() {
return makeNot(not, checkAccessMulti(n, a, true));
}
}
multiAcsCheck
= singleAcsCheck+
acsString = multiAcsCheck
當我需要幫助
我有(如果沒有其他人我還沒有遇到呢!)的主要問題是處理優先用()和OR子句。這可能是簡單的,但我已經爲此工作了幾天,並且有一些短缺。再次,我最終試圖實現的是輸入一個ACS字符串並輸出最終的布爾結果。各種ACS「命令」(例如上面例子中的'GM')應該進行方法調用來完成骯髒的工作。
不熟悉PEG.js,這聽起來像是一個問題,如果你在許多PEG.js社區中的一個站點上詢問它,可能會得到答案,在http://pegjs.majda.cz/development – 2014-10-12 20:39:29
上列出。請查看此響應:http:/ /stackoverflow.com/questions/19790748/make-a-expression-for-string-string-string-on-peg-js它處理可變長度列表。 – orange 2014-10-25 21:12:00
@BartKiers:我已經更新了示例以使用AND/OR。我不太清楚如何回答優先問題。我想從左到右評估,但是使用()優先分組。也許我沒有問正確的問題。 – NuSkooler 2014-11-04 19:52:37