Commit e336007fcf82c065e4651a28a8dc67a31be591e7

Golmote 2015-09-09T21:06:24

Add support for Bison

diff --git a/components.js b/components.js
index 3746a5d..69d2967 100644
--- a/components.js
+++ b/components.js
@@ -93,6 +93,11 @@ var components = {
 			"title": "BASIC",
 			"owner": "Golmote"
 		},
+		"bison": {
+			"title": "Bison",
+			"require": "c",
+			"owner": "Golmote"
+		},
 		"brainfuck": {
 			"title": "Brainfuck",
 			"owner": "Golmote"
diff --git a/components/prism-bison.js b/components/prism-bison.js
new file mode 100644
index 0000000..9a65a53
--- /dev/null
+++ b/components/prism-bison.js
@@ -0,0 +1,39 @@
+Prism.languages.bison = Prism.languages.extend('c', {});
+
+Prism.languages.insertBefore('bison', 'comment', {
+	'bison': {
+		// This should match all the beginning of the file
+		// including the prologue(s), the bison declarations and
+		// the grammar rules.
+		pattern: /^[\s\S]*?%%[\s\S]*?%%/,
+		inside: {
+			'c': {
+				// Allow for one level of nested braces
+				pattern: /%\{[\s\S]*?%\}|\{(?:\{[^}]*\}|[^{}])*\}/,
+				inside: {
+					'delimiter': {
+						pattern: /^%?\{|%?\}$/,
+						alias: 'punctuation'
+					},
+					'bison-variable': {
+						pattern: /[$@](?:<[^\s>]+>)?[\w$]+/,
+						alias: 'variable',
+						inside: {
+							'punctuation': /<|>/
+						}
+					},
+					rest: Prism.languages.c
+				}
+			},
+			'comment': Prism.languages.c.comment,
+			'string': Prism.languages.c.string,
+			'property': /\S+(?=:)/,
+			'keyword': /%\w+/,
+			'number': {
+				pattern: /(^|[^@])\b(?:0x[\da-f]+|\d+)/i,
+				lookbehind: true
+			},
+			'punctuation': /%[%?]|[|:;\[\]<>]/
+		}
+	}
+});
\ No newline at end of file
diff --git a/components/prism-bison.min.js b/components/prism-bison.min.js
new file mode 100644
index 0000000..c26f331
--- /dev/null
+++ b/components/prism-bison.min.js
@@ -0,0 +1 @@
+Prism.languages.bison=Prism.languages.extend("c",{}),Prism.languages.insertBefore("bison","comment",{bison:{pattern:/^[\s\S]*?%%[\s\S]*?%%/,inside:{c:{pattern:/%\{[\s\S]*?%\}|\{(?:\{[^}]*\}|[^{}])*\}/,inside:{delimiter:{pattern:/^%?\{|%?\}$/,alias:"punctuation"},"bison-variable":{pattern:/[$@](?:<[^\s>]+>)?[\w$]+/,alias:"variable",inside:{punctuation:/<|>/}},rest:Prism.languages.c}},comment:Prism.languages.c.comment,string:Prism.languages.c.string,property:/\S+(?=:)/,keyword:/%\w+/,number:{pattern:/(^|[^@])\b(?:0x[\da-f]+|\d+)/i,lookbehind:!0},punctuation:/%[%?]|[|:;\[\]<>]/}}});
\ No newline at end of file
diff --git a/examples/prism-bison.html b/examples/prism-bison.html
new file mode 100644
index 0000000..d76d81c
--- /dev/null
+++ b/examples/prism-bison.html
@@ -0,0 +1,110 @@
+<h1>Bison</h1>
+<p>To use this language, use the class "language-bison".</p>
+
+<h2>Comments</h2>
+<pre><code>// Single-line comment
+/* Multi-line
+comment */</code></pre>
+
+<h2>C prologue and Bison declarations</h2>
+<pre><code>%{
+  #include &lt;stdio.h>
+  #include &lt;math.h>
+  int yylex (void);
+  void yyerror (char const *);
+%}
+
+%define api.value.type {double}
+%token NUM
+%union { char *string; }
+%%
+%%</code></pre>
+
+<h2>Grammar rules</h2>
+<pre><code>%%
+exp:
+  NUM           { $$ = $1;           }
+| exp exp '+'   { $$ = $1 + $2;      }
+| exp exp '-'   { $$ = $1 - $2;      }
+| exp exp '*'   { $$ = $1 * $2;      }
+| exp exp '/'   { $$ = $1 / $2;      }
+| exp exp '^'   { $$ = pow($1, $2);  }  /* Exponentiation */
+| exp 'n'       { $$ = -$1;          }  /* Unary minus    */
+;
+
+$@1: %empty { a(); };
+$@2: %empty { c(); };
+$@3: %empty { d(); };
+exp: $@1 "b" $@2 $@3 "e" { f(); };
+%%</code></pre>
+
+<h2>Full example</h2>
+<pre><code>/* Mini Calculator */
+/* calc.y */
+
+%{
+#include "heading.h"
+int yyerror(char *s);
+int yylex(void);
+%}
+
+%union{
+  int		int_val;
+  string*	op_val;
+}
+
+%start	input 
+
+%token	&lt;int_val>	INTEGER_LITERAL
+%type	&lt;int_val>	exp
+%left	PLUS
+%left	MULT
+
+%%
+
+input:		/* empty */
+		| exp	{ cout &lt;&lt; "Result: " &lt;&lt; $1 &lt;&lt; endl; }
+		;
+
+exp:		INTEGER_LITERAL	{ $$ = $1; }
+		| exp PLUS exp	{ $$ = $1 + $3; }
+		| exp MULT exp	{ $$ = $1 * $3; }
+		;
+
+%%
+
+int yyerror(string s)
+{
+  extern int yylineno;	// defined and maintained in lex.c
+  extern char *yytext;	// defined and maintained in lex.c
+  
+  cerr &lt;&lt; "ERROR: " &lt;&lt; s &lt;&lt; " at symbol \"" &lt;&lt; yytext;
+  cerr &lt;&lt; "\" on line " &lt;&lt; yylineno &lt;&lt; endl;
+  exit(1);
+}
+
+int yyerror(char *s)
+{
+  return yyerror(string(s));
+}</code></pre>
+
+<h2>Known failures</h2>
+<p>There are certain edge cases where Prism will fail.
+	There are always such cases in every regex-based syntax highlighter.
+	However, Prism dares to be open and honest about them.
+	If a failure is listed here, it doesn’t mean it will never be fixed. This is more of a “known bugs” list, just with a certain type of bug.
+</p>
+
+<h3>Comment-like substring</h3>
+<pre><code>"This string is // broken"</code></pre>
+
+<h3>Two levels of nesting inside C section</h3>
+<pre><code>{
+	if($1) {
+		if($2) {
+
+		}
+	}
+} // <- Broken
+%%
+%%</code></pre>
\ No newline at end of file
diff --git a/tests/languages/bison/c_feature.test b/tests/languages/bison/c_feature.test
new file mode 100644
index 0000000..a131ec3
--- /dev/null
+++ b/tests/languages/bison/c_feature.test
@@ -0,0 +1,56 @@
+%{
+	#include <stdio.h>
+%}
+%code {
+	if(foo) {
+
+	}
+}
+%%
+exp:
+	NUM {
+		$$ = f($3, $4);
+		@$.first_column = @1.first_column;
+		$result = $left + $<itype>1;
+	}
+%%
+
+----------------------------------------------------
+
+[
+	["bison", [
+		["c", [
+			["delimiter", "%{"],
+			["macro", ["#include ", ["string", "<stdio.h>"]]],
+			["delimiter", "%}"]
+		]],
+		["keyword", "%code"],
+		["c", [
+			["delimiter", "{"],
+			["keyword", "if"], ["punctuation", "("], "foo", ["punctuation", ")"],
+			["punctuation", "{"], ["punctuation", "}"],
+			["delimiter", "}"]
+		]],
+		["punctuation", "%%"],
+		["property", "exp"], ["punctuation", ":"],
+		"\r\n\tNUM ",
+		["c", [
+			["delimiter", "{"],
+			["bison-variable", ["$$"]], ["operator", "="],
+			["function", "f"], ["punctuation", "("],
+			["bison-variable", ["$3"]], ["punctuation", ","],
+			["bison-variable", ["$4"]], ["punctuation", ")"], ["punctuation", ";"],
+			["bison-variable", ["@$"]], ["punctuation", "."], "first_column ", ["operator", "="],
+			["bison-variable", ["@1"]], ["punctuation", "."], "first_column", ["punctuation", ";"],
+			["bison-variable", ["$result"]], ["operator", "="],
+			["bison-variable", ["$left"]], ["operator", "+"],
+			["bison-variable", ["$", ["punctuation", "<"], "itype", ["punctuation", ">"], "1"]], ["punctuation", ";"],
+			["delimiter", "}"]
+		]],
+		["punctuation", "%%"]
+	]]
+]
+
+----------------------------------------------------
+
+Checks for C inside Bison, along with special Bison variables.
\ No newline at end of file
diff --git a/tests/languages/bison/comment_feature.test b/tests/languages/bison/comment_feature.test
new file mode 100644
index 0000000..15ed152
--- /dev/null
+++ b/tests/languages/bison/comment_feature.test
@@ -0,0 +1,25 @@
+// Foobar
+/* Foo
+bar */
+%%
+// Foobar
+/* Foo
+bar */
+%%
+
+----------------------------------------------------
+
+[
+	["bison", [
+		["comment", "// Foobar"],
+		["comment", "/* Foo\r\nbar */"],
+		["punctuation", "%%"],
+		["comment", "// Foobar"],
+		["comment", "/* Foo\r\nbar */"],
+		["punctuation", "%%"]
+	]]
+]
+
+----------------------------------------------------
+
+Checks for comments.
\ No newline at end of file
diff --git a/tests/languages/bison/keyword_feature.test b/tests/languages/bison/keyword_feature.test
new file mode 100644
index 0000000..49fb373
--- /dev/null
+++ b/tests/languages/bison/keyword_feature.test
@@ -0,0 +1,22 @@
+%union
+%token
+%%
+exp: %empty
+%%
+
+----------------------------------------------------
+
+[
+	["bison", [
+		["keyword", "%union"],
+		["keyword", "%token"],
+		["punctuation", "%%"],
+		["property", "exp"], ["punctuation", ":"],
+		["keyword", "%empty"],
+		["punctuation", "%%"]
+	]]
+]
+
+----------------------------------------------------
+
+Checks for keywords.
\ No newline at end of file
diff --git a/tests/languages/bison/number_feature.test b/tests/languages/bison/number_feature.test
new file mode 100644
index 0000000..ddbacff
--- /dev/null
+++ b/tests/languages/bison/number_feature.test
@@ -0,0 +1,15 @@
+42
+0
+0xBadFace
+
+----------------------------------------------------
+
+[
+	["number", "42"],
+	["number", "0"],
+	["number", "0xBadFace"]
+]
+
+----------------------------------------------------
+
+Checks for numbers.
\ No newline at end of file
diff --git a/tests/languages/bison/property_feature.test b/tests/languages/bison/property_feature.test
new file mode 100644
index 0000000..c1b6cb2
--- /dev/null
+++ b/tests/languages/bison/property_feature.test
@@ -0,0 +1,21 @@
+%%
+foo:
+bar_42:
+$@1:
+%%
+
+----------------------------------------------------
+
+[
+	["bison", [
+		["punctuation", "%%"],
+		["property", "foo"], ["punctuation", ":"],
+		["property", "bar_42"], ["punctuation", ":"],
+		["property", "$@1"], ["punctuation", ":"],
+		["punctuation", "%%"]
+	]]
+]
+
+----------------------------------------------------
+
+Checks for properties.
\ No newline at end of file
diff --git a/tests/languages/bison/string_feature.test b/tests/languages/bison/string_feature.test
new file mode 100644
index 0000000..3f3f6c0
--- /dev/null
+++ b/tests/languages/bison/string_feature.test
@@ -0,0 +1,21 @@
+%%
+foo: 'foo' "foo";
+bar: '\'' "\"";
+%%
+
+----------------------------------------------------
+
+[
+	["bison", [
+		["punctuation", "%%"],
+		["property", "foo"], ["punctuation", ":"],
+		["string", "'foo'"], ["string", "\"foo\""], ["punctuation", ";"],
+		["property", "bar"], ["punctuation", ":"],
+		["string", "'\\''"], ["string", "\"\\\"\""], ["punctuation", ";"],
+		["punctuation", "%%"]
+	]]
+]
+
+----------------------------------------------------
+
+Checks for strings.
\ No newline at end of file