From 472ec28762a94034737fcd8f055efc824dfdebc2 Mon Sep 17 00:00:00 2001 From: Sergio Date: Fri, 10 Feb 2023 14:56:27 -0300 Subject: [PATCH] Fixing bug when there is only one reserved word. Collecting implicit lex rules before other transformations. --- cfg2peg.lua | 7 +++-- spec/abnf_spec.lua | 6 ++-- spec/cfg2peg_spec.lua | 8 +++--- spec/reserved_spec.lua | 8 +++--- spec/toy_spec.lua | 63 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 13 deletions(-) create mode 100644 spec/toy_spec.lua diff --git a/cfg2peg.lua b/cfg2peg.lua index fd344e2..9d9fbad 100644 --- a/cfg2peg.lua +++ b/cfg2peg.lua @@ -459,7 +459,7 @@ function Cfg2Peg:collectKeywords () if nKey > 0 then local pKey if nKey == 1 then - pKey = Node.char(tKey) + pKey = Node.char(tKey[1]) else pKey = {} for i, v in ipairs(tKey) do @@ -502,7 +502,7 @@ end function Cfg2Peg:convertLexRule (ruleId) self.ruleId = ruleId or self.ruleId self:initId() - self:checkImplicitLexRulesG() + --self:checkImplicitLexRulesG() self:collectKeywords() self:checkLexicalPrefixes() end @@ -571,6 +571,9 @@ function Cfg2Peg:convert (ruleId, checkIdReserved) end self:initConflictStats() + if checkIdReserved then + self:checkImplicitLexRulesG() +end for i, var in ipairs(self.peg:getVars()) do if Grammar.isSynRule(var) then diff --git a/spec/abnf_spec.lua b/spec/abnf_spec.lua index e44b738..eaf3551 100644 --- a/spec/abnf_spec.lua +++ b/spec/abnf_spec.lua @@ -97,9 +97,6 @@ BIT <- [0-1] DIGIT <- [0-9] HEX_DIGIT <- [0-9] / [a-f] / [A-F] EOF <- !. -__rep_001 <- repetition __rep_001 / repetition &(')' / '/' / ']' / EOF / ID) -__IdBegin <- LETTER -__IdRest <- LETTER / DIGIT / '-' ZLex_001 <- '=' ZLex_002 <- '/' ZLex_003 <- '*' @@ -107,6 +104,9 @@ ZLex_004 <- '(' ZLex_005 <- ')' ZLex_006 <- '[' ZLex_007 <- ']' +__rep_001 <- repetition __rep_001 / repetition &(')' / '/' / ']' / EOF / ID) +__IdBegin <- LETTER +__IdRest <- LETTER / DIGIT / '-' ]] checkConversionToPeg(g, peg, {prefix = true, reserved = true, idRule = 'ID'}) diff --git a/spec/cfg2peg_spec.lua b/spec/cfg2peg_spec.lua index 33ef237..ca41dad 100644 --- a/spec/cfg2peg_spec.lua +++ b/spec/cfg2peg_spec.lua @@ -228,10 +228,10 @@ describe("Transforming a CFG into an equivalent PEG\n", function() a <- ZLex_001 / ZLex_002 b <- ZLex_001 / ZLex_001 ZLex_002 Id <- !__Keywords [a-z] [a-z0-9]* - __IdBegin <- [a-z] - __IdRest <- [a-z0-9] ZLex_001 <- 'a' !__IdRest ZLex_002 <- 'y' !__IdRest + __IdBegin <- [a-z] + __IdRest <- [a-z0-9] __Keywords <- ZLex_001 / ZLex_002 ]] @@ -255,13 +255,13 @@ describe("Transforming a CFG into an equivalent PEG\n", function() z <- id Number <- ('x' / 'X') [0-9]+ !__IdRest id <- !__Keywords [a-z] [a-z0-9]* - __IdBegin <- [a-z] - __IdRest <- [a-z0-9] ZLex_001 <- 'there' !__IdRest ZLex_002 <- 'AB' !__IdRest ZLex_003 <- 'x9' !__IdRest ZLex_004 <- '3' ZLex_005 <- 'bb' !__IdRest + __IdBegin <- [a-z] + __IdRest <- [a-z0-9] __Keywords <- Number / ZLex_001 / ZLex_002 / ZLex_003 / ZLex_005 ]] diff --git a/spec/reserved_spec.lua b/spec/reserved_spec.lua index 96025e1..e253c1d 100644 --- a/spec/reserved_spec.lua +++ b/spec/reserved_spec.lua @@ -64,10 +64,10 @@ describe("Transforming a CFG into an equivalent PEG\n", function() a <- ZLex_001 / ZLex_002 b <- ZLex_001 / ZLex_001 ZLex_002 Id <- !__Keywords [a-z] [a-z0-9]* - __IdBegin <- [a-z] - __IdRest <- [a-z0-9] ZLex_001 <- 'a' !__IdRest ZLex_002 <- 'y' !__IdRest + __IdBegin <- [a-z] + __IdRest <- [a-z0-9] __Keywords <- ZLex_001 / ZLex_002 ]] @@ -91,13 +91,13 @@ describe("Transforming a CFG into an equivalent PEG\n", function() z <- id Number <- ('x' / 'X') [0-9]+ !__IdRest id <- !__Keywords [a-z] [a-z0-9]* - __IdBegin <- [a-z] - __IdRest <- [a-z0-9] ZLex_001 <- 'there' !__IdRest ZLex_002 <- 'AB' !__IdRest ZLex_003 <- 'x9' !__IdRest ZLex_004 <- '3' ZLex_005 <- 'bb' !__IdRest + __IdBegin <- [a-z] + __IdRest <- [a-z0-9] __Keywords <- Number / ZLex_001 / ZLex_002 / ZLex_003 / ZLex_005 ]] diff --git a/spec/toy_spec.lua b/spec/toy_spec.lua new file mode 100644 index 0000000..fd5f51f --- /dev/null +++ b/spec/toy_spec.lua @@ -0,0 +1,63 @@ +local Parser = require 'pegparser.parser' +local Pretty = require 'pegparser.pretty' +local Util = require'pegparser.util' +local Cfg2Peg = require'pegparser.cfg2peg' +local Coder = require'pegparser.coder' + +local function checkConversionToPeg (stringG, stringPeg, config) + local g = Parser.match(stringG) + assert.is_not_nil(g) + + config = config or {} + + local c2p = Cfg2Peg.new(g) + c2p:setUsePrefix(config.prefix) + c2p:setUseUnique(config.unique) + c2p:convert(config.idRule, config.reserved) + + local peg = c2p.peg + local pretty = Pretty.new() + + local equal = Util.sameWithoutSpace(pretty:printg(peg, nil, true), stringPeg) + + if not equal then + print("---- Different ----\n") + print(">>>> Generated PEG <<<<") + print(pretty:printg(peg, nil, true)) + print("\n**** Expected PEG ****") + print(stringPeg) + print("") + end + + assert.is_true(equal) +end + + +describe("Transforming a CFG into an equivalent PEG\n", function() + + local pretty = Pretty.new() + + + test("Converting DOT grammar - Dealing with reserved words", function() + local g = [[ +init <- a b +a <- 'x'* 'x' +b <- 'x' +ID <- [a-z][a-z]* +]] + + local peg = [[ +init <- a b +a <- __rep_001 ZLex_001 +b <- ZLex_001 +ID <- !__Keywords [a-z][a-z]* +ZLex_001 <- 'x' !__IdRest +__rep_001 <- ZLex_001 __rep_001 / &ZLex_001 +__IdBegin <- [a-z] +__IdRest <- [a-z] +__Keywords <- ZLex_001 +]] + checkConversionToPeg(g, peg, {unique = true, idRule = "ID", reserved = "true"}) + + end) +end)