aboutsummaryrefslogtreecommitdiff
path: root/1-24_syntax-checker.c
diff options
context:
space:
mode:
authorzlg <zlg@zlg.space>2013-02-13 20:48:44 -0600
committerzlg <zlg@zlg.space>2013-02-13 20:48:44 -0600
commit5018e06c580dd21c958ec1672c26a3448faf0c55 (patch)
treecebbb56dad0a6b821cad3712c7977f6f9b0086ab /1-24_syntax-checker.c
parentFix 1-09's solution (diff)
downloadknr-5018e06c580dd21c958ec1672c26a3448faf0c55.tar.gz
knr-5018e06c580dd21c958ec1672c26a3448faf0c55.tar.bz2
knr-5018e06c580dd21c958ec1672c26a3448faf0c55.tar.xz
knr-5018e06c580dd21c958ec1672c26a3448faf0c55.zip
Add license file, reorganize project
Diffstat (limited to '1-24_syntax-checker.c')
-rw-r--r--1-24_syntax-checker.c163
1 files changed, 0 insertions, 163 deletions
diff --git a/1-24_syntax-checker.c b/1-24_syntax-checker.c
deleted file mode 100644
index 019b9bc..0000000
--- a/1-24_syntax-checker.c
+++ /dev/null
@@ -1,163 +0,0 @@
-#include <stdio.h>
-
-/* The C Programming Language: 2nd Edition
- * Exercise 1-24:
- * "Write a program to check a C program for rudimentary syntax errors like
- * unbalanced parentheses, brackets, and braces. Don't forget about quotes, both
- * single and double, escape sequences, and comments. (This program is hard if
- * you do it in full generality.)"
- *
- * Proksima from Freenode's ##c helped me understand full generality where
- * Ixquick, Wikipedia, and StackOverflow all failed: a program that has full
- * generality handles all use cases. In this case, my program should report no
- * errors from a well formed C source file, and return correct errors for every
- * non-valid C source file.
- *
- * I can tackle this one the same way I tackled the previous exercise: with a
- * FSM. The trick is in catching the mismatched levels.
- *
- * Post-solution note: switch() would've made this MUCH shorter...
- */
-
-char c;
-
-/* Set the state/count variables */
-int linenr, parens, brackets, braces, singqs, dubqs, escapes, mcomms, scomms = 0;
-
-int main() {
- linenr = 1;
- // Begin streaming!
- while ((c = getchar()) != EOF) {
- if (scomms == 1) {
- if (c == '\n') {
- scomms--;
- } else {
- continue;
- }
- } else if (mcomms == 1) {
- if (c == '*') {
- if (getchar() == '/') {
- mcomms--;
- }
- }
- } else {
- // Check for escape sequences
- if (c == '\\') {
- escapes++;
- c = getchar();
- // This does not detect all sequences; just the ones covered in Chapter 1.
- if (c != '\\' && c != 't' && c != '\'' && c != '"' && c != 'n' && c != 'b' && c != '0') {
- break;
- } else {
- escapes--;
- }
- }
- // Newline behavior
- if (c == '\n') {
- if (singqs > 0 || dubqs > 0) {
- break;
- }
- linenr++;
- }
- // Parentheses
- if (c == '(') {
- parens++;
- }
- if (c == ')') {
- parens -= 1;
- if (parens < 0) {
- break;
- }
- }
- // Brackets
- if (c == '[') {
- brackets++;
- }
- if (c == ']') {
- brackets--;
- if (brackets < 0) {
- break;
- }
- }
- // Braces
- if (c == '{') {
- braces++;
- }
- if (c == '}') {
- braces--;
- if (braces < 0) {
- break;
- }
- }
- // Double quotes
- if (c == '"') {
- if (dubqs == 0) {
- dubqs++;
- } else {
- dubqs--;
- }
- }
- // Single quotes, which are only checked outside of doubles.
- if (c == '\'' && dubqs == 0) {
- if (singqs == 0) {
- singqs++;
- } else {
- singqs--;
- }
- }
- // Comment detection
- if (c == '/') {
- if (getchar() == '*') {
- mcomms++;
- }
- if (getchar() == '/') {
- scomms++;
- }
- }
- }
- }
-
- if (escapes > 0) {
- printf("Invalid escape sequence on line %d!\n", linenr);
- return 1;
- }
- if (singqs > 0) {
- printf("Unclosed single quote on line %d!\n", linenr);
- return 1;
- }
- if (dubqs > 0) {
- printf("Unclosed double quote on line %d!\n", linenr);
- return 1;
- }
- if (brackets > 0) {
- printf("Unclosed brackets on line %d!\n", linenr);
- return 1;
- }
- if (brackets < 0) {
- printf("Too many close brackets on line %d!\n", linenr);
- return 1;
- }
- if (parens > 0) {
- printf("Unclosed parenthesis on line %d!\n", linenr);
- return 1;
- }
- if (parens < 0) {
- printf("Too many close parentheses on line %d!\n", linenr);
- return 1;
- }
- if (braces > 0) {
- printf("Unclosed braces on line %d!\n", linenr);
- return 1;
- }
- if (braces < 0) {
- printf("Too many close braces on line %d!\n", linenr);
- return 1;
- }
- if (mcomms == 1) {
- printf("Unclosed comment at end of file!\n");
- return 1;
- }
-
- printf("All clean.\n");
- return 0;
-}