From 29b9ffb4741f1d04734b289c398008337a5f031f Mon Sep 17 00:00:00 2001 From: Andreas Abel Date: Tue, 5 Oct 2021 15:59:17 +0200 Subject: [PATCH] Fix #388: check token defs for empty regular expression --- source/CHANGELOG.md | 2 ++ source/src/BNFC/GetCF.hs | 24 ++++++++++++++++++++++-- testing/fail-lbnf/388-empty-regex.cf | 3 +++ testing/fail-lbnf/388-empty-regex.err | 4 ++++ 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 testing/fail-lbnf/388-empty-regex.cf create mode 100644 testing/fail-lbnf/388-empty-regex.err diff --git a/source/CHANGELOG.md b/source/CHANGELOG.md index 56fe6dd5..ffb87113 100644 --- a/source/CHANGELOG.md +++ b/source/CHANGELOG.md @@ -2,6 +2,8 @@ Unreleased +* LBNF: empty tokens types are now forbidden [#388] + # 2.9.3 Andreas Abel September 2021 diff --git a/source/src/BNFC/GetCF.hs b/source/src/BNFC/GetCF.hs index 919b92c0..a02852e2 100644 --- a/source/src/BNFC/GetCF.hs +++ b/source/src/BNFC/GetCF.hs @@ -47,6 +47,7 @@ import System.IO (hPutStrLn, stderr) -- Local imports: import qualified BNFC.Abs as Abs +import BNFC.Abs (Reg(RAlts)) import BNFC.Par import BNFC.CF @@ -537,9 +538,16 @@ checkComments cf = concat where prags = cfgPragmas cf --- | Check if any of the user-defined terminal categories is nullable. +-- | Check if any of the user-defined terminal categories is nullable or empty. checkTokens :: CFG f -> Maybe String -checkTokens cf +checkTokens cf = + case catMaybes [ checkTokensEmpty cf, checkTokensNullable cf ] of + [] -> Nothing + ss -> Just $ concat ss + +-- | Check if any of the user-defined terminal categories is nullable. +checkTokensNullable :: CFG f -> Maybe String +checkTokensNullable cf | null pxs = Nothing | otherwise = Just $ unlines $ concat [ [ "ERROR: The following tokens accept the empty string:" ] @@ -548,6 +556,18 @@ checkTokens cf where pxs = [ px | TokenReg px _ regex <- cfgPragmas cf, nullable regex ] +-- | Check if any of the user-defined terminal categories is nullable. +checkTokensEmpty :: CFG f -> Maybe String +checkTokensEmpty cf + | null pxs = Nothing + | otherwise = Just $ unlines $ concat + [ [ "ERROR: The following tokens accept nothing:" ] + , printNames pxs + ] + where + -- The regular expression is already simplified, so we match against 0 directly. + pxs = [ px | TokenReg px _ (RAlts "") <- cfgPragmas cf ] + -- we should actually check that -- (1) coercions are always between variants diff --git a/testing/fail-lbnf/388-empty-regex.cf b/testing/fail-lbnf/388-empty-regex.cf new file mode 100644 index 00000000..d774c0eb --- /dev/null +++ b/testing/fail-lbnf/388-empty-regex.cf @@ -0,0 +1,3 @@ +-- 2021-10-05 Issue #388, empty regular expression + +token Empty [""]+ | [""] | (char - char); diff --git a/testing/fail-lbnf/388-empty-regex.err b/testing/fail-lbnf/388-empty-regex.err new file mode 100644 index 00000000..47ec4ccd --- /dev/null +++ b/testing/fail-lbnf/388-empty-regex.err @@ -0,0 +1,4 @@ +ERROR: The following tokens accept nothing: + fail-lbnf/388-empty-regex.cf:3:7: Empty + +Aborting. (Use option --force to continue despite errors.)