codemirror-lang-dimacs 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +8 -0
- package/README.md +78 -2
- package/dist/highlight.d.ts +2 -0
- package/dist/index.cjs +50 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +47 -0
- package/package.json +44 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (C) 2026 by Johannes Schuster <johannes.c.schuster@proton.me>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
lang-dimacs is licensed under the MIT licence in LICENSE.
|
|
2
|
+
|
|
3
|
+
The Lezer grammar (dimacs.grammar) and the tests are written by hand. What they accept
|
|
4
|
+
was worked out by reading the DIMACS and solution parser of CaDiCaL
|
|
5
|
+
(https://github.com/arminbiere/cadical, src/parse.cpp; version and checksum in
|
|
6
|
+
spec/SOURCE of the lang-dimacs repository), which is MIT-licensed, Copyright (c) Armin
|
|
7
|
+
Biere and others. No CaDiCaL code is copied. CaDiCaL itself is used only as a test
|
|
8
|
+
oracle and is not distributed.
|
package/README.md
CHANGED
|
@@ -1,3 +1,79 @@
|
|
|
1
|
-
#
|
|
1
|
+
# codemirror-lang-dimacs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
DIMACS CNF language support for [CodeMirror 6](https://codemirror.net/): a Lezer parser
|
|
4
|
+
for the dialects that [CaDiCaL](https://github.com/arminbiere/cadical) reads, with
|
|
5
|
+
highlighting.
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import {EditorView, basicSetup} from "codemirror"
|
|
9
|
+
import {dimacs} from "codemirror-lang-dimacs"
|
|
10
|
+
|
|
11
|
+
new EditorView({extensions: [basicSetup, dimacs()], parent: document.body})
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
For solver output in the SAT competition format (`s` and `v` lines), configure the
|
|
15
|
+
second top rule:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import {LanguageSupport} from "@codemirror/language"
|
|
19
|
+
import {dimacsLanguage} from "codemirror-lang-dimacs"
|
|
20
|
+
|
|
21
|
+
new LanguageSupport(dimacsLanguage.configure({top: "Solution"}))
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Scope
|
|
25
|
+
|
|
26
|
+
- `p cnf <max-var> <num-clauses>` and `p inccnf` files, with comments and, after the
|
|
27
|
+
clauses, cubes (`a <literals> 0`).
|
|
28
|
+
- Solutions: comments, one status line `s SATISFIABLE`, `s UNSATISFIABLE` or `s UNKNOWN`,
|
|
29
|
+
then `v` lines.
|
|
30
|
+
|
|
31
|
+
Not covered: `p sat`, WCNF, QDIMACS, XOR lines, `p knf`. CaDiCaL rejects every problem
|
|
32
|
+
line but `p cnf` and `p inccnf`.
|
|
33
|
+
|
|
34
|
+
The parser is permissive: it accepts any white space (space, tab, CR, LF) in the problem
|
|
35
|
+
line, cubes after a `p cnf` header, and header counts that do not match the body.
|
|
36
|
+
Checking those is left to a linter; this package has none.
|
|
37
|
+
|
|
38
|
+
## What CaDiCaL accepts
|
|
39
|
+
|
|
40
|
+
Read from `src/parse.cpp` of CaDiCaL 3.0.1 (source and checksum in `spec/SOURCE` of the
|
|
41
|
+
repository) and checked against its `cadical` binary with the files in `fixtures/`.
|
|
42
|
+
|
|
43
|
+
1. Before the problem line, lines starting with `c` are comments, and white space
|
|
44
|
+
(space, tab, CR, LF) before them is skipped. A header comment must end with a newline.
|
|
45
|
+
2. In a header comment, the text from the first `-` to the end of the line is passed to
|
|
46
|
+
CaDiCaL as an option; only `--name[=value]` takes effect. Comments after the problem
|
|
47
|
+
line are not read for options.
|
|
48
|
+
3. Problem line: `p cnf <max-var> <num-clauses>`, or `p inccnf` without numbers, ended by
|
|
49
|
+
a newline. Between `p` and the format any spaces and tabs; between the format and the
|
|
50
|
+
numbers any white space (C `isspace`), newlines included. (`--strict` demands single spaces.)
|
|
51
|
+
4. In the body, space, tab, CR and LF separate tokens. A literal is an optional `-` and
|
|
52
|
+
digits, followed by white space, end of file or `c`. Leading zeros are allowed: `007`
|
|
53
|
+
is `7`, and `0`, `00` and `-0` all end a clause. Clauses may span lines and share
|
|
54
|
+
them.
|
|
55
|
+
5. `c` at the start of a token starts a comment to the end of the line, also directly
|
|
56
|
+
after a literal (`1 -2 0c note`).
|
|
57
|
+
6. `p inccnf` only: the first `a` at the start of a token ends the clauses. Each cube is
|
|
58
|
+
`a`, literals, `0`; an `a` before that `0` is an error. After a cube's `0` only white
|
|
59
|
+
space, another `a` or the end of the file may follow, and a comment only if it runs to
|
|
60
|
+
the end of the file.
|
|
61
|
+
7. `a` in a `p cnf` file is an error.
|
|
62
|
+
8. Unless `--force` is given, the clause count must match and no literal may exceed
|
|
63
|
+
`<max-var>`.
|
|
64
|
+
9. A solution (`cadical -r`) is: lines starting with `c`, then exactly `s SATISFIABLE`,
|
|
65
|
+
then lines starting with `v ` holding literals, the last ended by `0`. A comment
|
|
66
|
+
directly after a literal is an error there. The `cadical` binary itself prints
|
|
67
|
+
`s SATISFIABLE`, `s UNSATISFIABLE` or `c UNKNOWN`, and exits with 10, 20 or 0.
|
|
68
|
+
|
|
69
|
+
## Hand-written files
|
|
70
|
+
|
|
71
|
+
Every source file is hand-written; nothing is generated:
|
|
72
|
+
|
|
73
|
+
- `src/dimacs.grammar`, `src/dimacs.grammar.d.ts`
|
|
74
|
+
- `src/highlight.ts`, `src/index.ts`
|
|
75
|
+
- `test/dimacs.txt`, `test/solution.txt`, `test/test.js`, `test/fixtures.js`
|
|
76
|
+
- `rollup.config.js`, `tsconfig.json`
|
|
77
|
+
|
|
78
|
+
The parser in `dist/` is generated from `src/dimacs.grammar` by `@lezer/generator` when
|
|
79
|
+
the package is built.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var lr = require('@lezer/lr');
|
|
4
|
+
var highlight = require('@lezer/highlight');
|
|
5
|
+
var language = require('@codemirror/language');
|
|
6
|
+
|
|
7
|
+
const dimacsHighlighting = highlight.styleTags({
|
|
8
|
+
LineComment: highlight.tags.lineComment,
|
|
9
|
+
"p CubeMarker s v": highlight.tags.keyword,
|
|
10
|
+
Format: highlight.tags.typeName,
|
|
11
|
+
Number: highlight.tags.number,
|
|
12
|
+
PositiveLiteral: highlight.tags.variableName,
|
|
13
|
+
NegativeLiteral: highlight.tags.special(highlight.tags.variableName),
|
|
14
|
+
Terminator: highlight.tags.separator,
|
|
15
|
+
Status: highlight.tags.bool,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
|
19
|
+
const parser = lr.LRParser.deserialize({
|
|
20
|
+
version: 14,
|
|
21
|
+
states: "%dO_QPOOOdQPOOOiYQO'#C_QqQPOOO!PQPO'#CkQ!UQPOOO!ZYQO,58yOOQO,58y,58yOOQO'#Cx'#CxOOQO'#Cq'#CqO!`QPO'#CdOOQO'#Cd'#CdOOQO'#Cp'#CpQqQPOOO!kQPO'#ChOOQO'#Cr'#CrQzQPOOOOQO,59V,59VO!vQPO'#CnOOQO'#Cs'#CsQ!UQPOOO#XYQO1G.eOOQO-E6o-E6oOOQO,59O,59OOOQO-E6n-E6nO#^QPO,59SOOQO,59S,59SOOQO-E6p-E6pO#iQPO,59YOOQO,59Y,59YOOQO-E6q-E6qOOQO7+$P7+$POOQO1G.n1G.nOOQO1G.t1G.t",
|
|
22
|
+
stateData: "$O~OkOSPOS~OkOS~OSQO~O`SO~OTUOVVO~OXWOYWOZZO]^O~OaaO~OcbO~OUeO~OXWOYWOZgO~OXWOYWOZjO~OXWOYWOZmOcbXhbX~OUoO~OXWOYWOZpO~OXWOYWOZqOcbahba~OXYZ~",
|
|
23
|
+
goto: "#OmPPPnPPPPqPPPuPPzPP}P!R!X!h!oPPPP!uRROT[R]V_R]`RTPTcTdQ]RRh]SYR]UfYilQi^RlbS`R]Rk`QdTRnd_XRY]^bil",
|
|
24
|
+
nodeNames: "⚠ LineComment Dimacs ProblemLine p Format Number Format Clause PositiveLiteral NegativeLiteral Terminator Cube CubeMarker Solution StatusLine s Status ValueLine v",
|
|
25
|
+
maxTerm: 28,
|
|
26
|
+
propSources: [dimacsHighlighting],
|
|
27
|
+
skippedNodes: [0,1],
|
|
28
|
+
repeatNodeCount: 4,
|
|
29
|
+
tokenData: "(y~R_XY!QYZ!Q]^!Qpq!Q}!O!c!Q!R#P!R![#^!u!v#h!w!x${#T#U%t#V#W%y#]#^'u#d#e(j#g#h(o#j#k(t~!VSk~XY!QYZ!Q]^!Qpq!Q~!fQ!Q!R!l!R![!w~!qQZP!Q!R!l!R![!w~!|PY~!Q![!wR#WQUQZP!Q!R#P!R![#^R#ePUQXP!Q![#^~#kP!c!d#n~#qP!v!w#t~#wP!k!l#z~#}P!u!v$Q~$TP!h!i$W~$ZP!k!l$^~$aP!c!d$d~$gP!d!e$j~$mP!n!o$p~$sP!g!h$v~${Oa~~%OP!p!q%R~%UQ!m!n%[!u!v#h~%_P!p!q%b~%eP!q!r%h~%kP!y!z%n~%qP!p!q$v~%yO]~R&OUPPOY&bZ#b&b#b#c&y#c;'S&b;'S;=`&s<%lO&bP&gSPPOY&bZ;'S&b;'S;=`&s<%lO&bP&vP;=`<%l&bR'OUPPOY&bZ#Y&b#Y#Z'b#Z;'S&b;'S;=`&s<%lO&bR'iSPPTQOY&bZ;'S&b;'S;=`&s<%lO&b~'xP#b#c'{~(OP#V#W(R~(UP#V#W(X~([P#b#c(_~(bP#Y#Z(e~(jOV~~(oOS~~(tO`~~(yOc~",
|
|
30
|
+
tokenizers: [0, 1],
|
|
31
|
+
topRules: {"Dimacs":[0,2],"Solution":[1,14]},
|
|
32
|
+
tokenPrec: 134
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
/// DIMACS CNF as CaDiCaL reads it (`p cnf` and `p inccnf`). For solver output in the
|
|
36
|
+
/// competition format, use `dimacsLanguage.configure({top: "Solution"})`.
|
|
37
|
+
const dimacsLanguage = language.LRLanguage.define({
|
|
38
|
+
name: "dimacs",
|
|
39
|
+
parser,
|
|
40
|
+
languageData: {
|
|
41
|
+
commentTokens: { line: "c" },
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
/// DIMACS language support for CodeMirror.
|
|
45
|
+
function dimacs() {
|
|
46
|
+
return new language.LanguageSupport(dimacsLanguage);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
exports.dimacs = dimacs;
|
|
50
|
+
exports.dimacsLanguage = dimacsLanguage;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { LRParser } from '@lezer/lr';
|
|
2
|
+
import { styleTags, tags } from '@lezer/highlight';
|
|
3
|
+
import { LRLanguage, LanguageSupport } from '@codemirror/language';
|
|
4
|
+
|
|
5
|
+
const dimacsHighlighting = styleTags({
|
|
6
|
+
LineComment: tags.lineComment,
|
|
7
|
+
"p CubeMarker s v": tags.keyword,
|
|
8
|
+
Format: tags.typeName,
|
|
9
|
+
Number: tags.number,
|
|
10
|
+
PositiveLiteral: tags.variableName,
|
|
11
|
+
NegativeLiteral: tags.special(tags.variableName),
|
|
12
|
+
Terminator: tags.separator,
|
|
13
|
+
Status: tags.bool,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// This file was generated by lezer-generator. You probably shouldn't edit it.
|
|
17
|
+
const parser = LRParser.deserialize({
|
|
18
|
+
version: 14,
|
|
19
|
+
states: "%dO_QPOOOdQPOOOiYQO'#C_QqQPOOO!PQPO'#CkQ!UQPOOO!ZYQO,58yOOQO,58y,58yOOQO'#Cx'#CxOOQO'#Cq'#CqO!`QPO'#CdOOQO'#Cd'#CdOOQO'#Cp'#CpQqQPOOO!kQPO'#ChOOQO'#Cr'#CrQzQPOOOOQO,59V,59VO!vQPO'#CnOOQO'#Cs'#CsQ!UQPOOO#XYQO1G.eOOQO-E6o-E6oOOQO,59O,59OOOQO-E6n-E6nO#^QPO,59SOOQO,59S,59SOOQO-E6p-E6pO#iQPO,59YOOQO,59Y,59YOOQO-E6q-E6qOOQO7+$P7+$POOQO1G.n1G.nOOQO1G.t1G.t",
|
|
20
|
+
stateData: "$O~OkOSPOS~OkOS~OSQO~O`SO~OTUOVVO~OXWOYWOZZO]^O~OaaO~OcbO~OUeO~OXWOYWOZgO~OXWOYWOZjO~OXWOYWOZmOcbXhbX~OUoO~OXWOYWOZpO~OXWOYWOZqOcbahba~OXYZ~",
|
|
21
|
+
goto: "#OmPPPnPPPPqPPPuPPzPP}P!R!X!h!oPPPP!uRROT[R]V_R]`RTPTcTdQ]RRh]SYR]UfYilQi^RlbS`R]Rk`QdTRnd_XRY]^bil",
|
|
22
|
+
nodeNames: "⚠ LineComment Dimacs ProblemLine p Format Number Format Clause PositiveLiteral NegativeLiteral Terminator Cube CubeMarker Solution StatusLine s Status ValueLine v",
|
|
23
|
+
maxTerm: 28,
|
|
24
|
+
propSources: [dimacsHighlighting],
|
|
25
|
+
skippedNodes: [0,1],
|
|
26
|
+
repeatNodeCount: 4,
|
|
27
|
+
tokenData: "(y~R_XY!QYZ!Q]^!Qpq!Q}!O!c!Q!R#P!R![#^!u!v#h!w!x${#T#U%t#V#W%y#]#^'u#d#e(j#g#h(o#j#k(t~!VSk~XY!QYZ!Q]^!Qpq!Q~!fQ!Q!R!l!R![!w~!qQZP!Q!R!l!R![!w~!|PY~!Q![!wR#WQUQZP!Q!R#P!R![#^R#ePUQXP!Q![#^~#kP!c!d#n~#qP!v!w#t~#wP!k!l#z~#}P!u!v$Q~$TP!h!i$W~$ZP!k!l$^~$aP!c!d$d~$gP!d!e$j~$mP!n!o$p~$sP!g!h$v~${Oa~~%OP!p!q%R~%UQ!m!n%[!u!v#h~%_P!p!q%b~%eP!q!r%h~%kP!y!z%n~%qP!p!q$v~%yO]~R&OUPPOY&bZ#b&b#b#c&y#c;'S&b;'S;=`&s<%lO&bP&gSPPOY&bZ;'S&b;'S;=`&s<%lO&bP&vP;=`<%l&bR'OUPPOY&bZ#Y&b#Y#Z'b#Z;'S&b;'S;=`&s<%lO&bR'iSPPTQOY&bZ;'S&b;'S;=`&s<%lO&b~'xP#b#c'{~(OP#V#W(R~(UP#V#W(X~([P#b#c(_~(bP#Y#Z(e~(jOV~~(oOS~~(tO`~~(yOc~",
|
|
28
|
+
tokenizers: [0, 1],
|
|
29
|
+
topRules: {"Dimacs":[0,2],"Solution":[1,14]},
|
|
30
|
+
tokenPrec: 134
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/// DIMACS CNF as CaDiCaL reads it (`p cnf` and `p inccnf`). For solver output in the
|
|
34
|
+
/// competition format, use `dimacsLanguage.configure({top: "Solution"})`.
|
|
35
|
+
const dimacsLanguage = LRLanguage.define({
|
|
36
|
+
name: "dimacs",
|
|
37
|
+
parser,
|
|
38
|
+
languageData: {
|
|
39
|
+
commentTokens: { line: "c" },
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
/// DIMACS language support for CodeMirror.
|
|
43
|
+
function dimacs() {
|
|
44
|
+
return new LanguageSupport(dimacsLanguage);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { dimacs, dimacsLanguage };
|
package/package.json
CHANGED
|
@@ -1,6 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codemirror-lang-dimacs",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"keywords": [
|
|
5
|
+
"codemirror",
|
|
6
|
+
"lezer",
|
|
7
|
+
"dimacs",
|
|
8
|
+
"sat"
|
|
9
|
+
],
|
|
10
|
+
"description": "DIMACS CNF language support for CodeMirror, as read by CaDiCaL",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"test": "mocha test/test.js test/fixtures.js",
|
|
13
|
+
"build": "rollup -c && tsc -p tsconfig.json --declaration --emitDeclarationOnly --outDir dist",
|
|
14
|
+
"prepare": "pnpm run build"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "dist/index.cjs",
|
|
18
|
+
"module": "dist/index.js",
|
|
19
|
+
"exports": {
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"require": "./dist/index.cjs"
|
|
22
|
+
},
|
|
23
|
+
"types": "dist/index.d.ts",
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@codemirror/language": "^6.0.0",
|
|
27
|
+
"@lezer/common": "^1.5.3",
|
|
28
|
+
"@lezer/highlight": "^1.0.0",
|
|
29
|
+
"@lezer/lr": "^1.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@lezer/generator": "^1.0.0",
|
|
33
|
+
"@rollup/plugin-typescript": "^12.1.4",
|
|
34
|
+
"@types/node": "^26.0.0",
|
|
35
|
+
"mocha": "^11.7.1",
|
|
36
|
+
"rollup": "^4.45.1",
|
|
37
|
+
"tslib": "^2.8.1",
|
|
38
|
+
"typescript": "^5.8.3"
|
|
39
|
+
},
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/jcschuster/lang-dimacs.git",
|
|
43
|
+
"directory": "packages/codemirror-lang-dimacs"
|
|
44
|
+
},
|
|
45
|
+
"license": "MIT"
|
|
46
|
+
}
|